[
  {
    "path": ".dockerignore",
    "content": ".git\nDockerfile\n.dockerignore\n"
  },
  {
    "path": ".envrc",
    "content": "use flake"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [a-h, joerdav]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Before you begin**\nPlease make sure you're using the latest version of the templ CLI (`go install github.com/a-h/templ/cmd/templ@latest`), and have upgraded your project to use the latest version of the templ runtime (`go get -u github.com/a-h/templ@latest`)\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nA small, self-contained, complete reproduction, uploaded to a GitHub repo, containing the minimum amount of files required to reproduce the behaviour, along with a list of commands that need to be run. Keep it simple.\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots or screen captures to help explain your problem.\n\n**Logs**\nIf the issue is related to IDE support, run through the LSP troubleshooting section at https://templ.guide/developer-tools/ide-support/#troubleshooting-1 and include logs from templ\n\n**`templ info` output**\nRun `templ info` and include the output.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. MacOS, Linux, Windows, WSL]\n - templ CLI version (`templ version`)\n- Go version (`go version`)\n- `gopls` version (`gopls version`)\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/copilot-instructions.md",
    "content": "# Coding standards\n\n## Behaviour\n\n* Always run `go fmt` after making changes to Go code.\n* Always run unit tests after making changes to Go code.\n\n## Environment setup\n\n* Ensure that the user has direnv installed, and that it is set up correctly in their shell. See https://direnv.net/docs/installation.html\n* Ensure that the user has Nix installed, and that it is set up correctly. See https://nixos.org/download.html\n* Ensure that the user has the direnv VS code extension installed, so that the `.envrc` file is automatically loaded when the project is opened in VS Code.\n\n### Background\n\ntempl has an `.envrc` file that is used to set up the development environment using a tool called `direnv`. There is a VS Code extension available that will automatically load this when you open the project in VS Code.\n\nThe `.envrc` file uses a Nix flake to set up the environment, so Nix is required to be installed.\n\nThe version of Go used is defined in the `flake.nix` file.\n\n## Build tasks\n\ntempl uses the `xc` task runner - https://github.com/joerdav/xc\n\nIf you run `xc` you can get see a list of the development tasks that can be run, or you can read the `README.md` file and see the `Tasks` section.\n\nThe most useful tasks for local development are:\n\n* `xc install-snapshot` - builds the templ CLI and installs it into `~/bin`. Ensure that this is in your path.\n* `xc generate` - generates Go code from the templ files in the project.\n* `xc test` - regenerates all templates, and runs the unit tests.\n* `xc test-short` - runs shorter tests, avoiding long running tests for filesystem watchers etc.\n* `xc fmt` - runs `gofmt` to format all Go code.\n* `xc lint` - run the same linting as run in the CI process.\n* `xc docs-run` - run the Docusaurus documentation site.\n\ntempl has a code generation step, this is automatically carried out using `xc test`.\n\nDon't install templ globally using `xc install-snapshot` or `go install`. Use the `xc generate` or `xc test-short` tasks to generate the code, which will also run the tests.\n\n## Commit messages\n\nThe project using https://www.conventionalcommits.org/en/v1.0.0/\n\nExamples:\n\n* `feat: support Go comments in templates, fixes #234\"`\n* `fix: ensure that the templ CLI works with Go 1.21, fixes #123`\n\n## Documentation\n\n* Documentation is written in Markdown, and is rendered using Docusaurus. The documentation is in the `docs` directory.\n* Update documentation when the behaviour of templ changes, or when new features are added.\n\n## Writing style\n\n* Use American English spelling to match the Go standard library, and HTML spec, e.g. \"color\".\n* Use the Oxford comma, e.g. \"apples, oranges, and bananas\".\n* Avoid use of emojis everywhere - in code, comments, commit messages, and documentation.\n* Be \"to the point\" and precise - avoid unnecessary words, don't use filler words like \"just\" or \"really\".\n* Use the active voice, e.g. \"templ generates code\" rather than \"code is generated by templ\".\n* Don't use emphatic words or phrases like \"very\", \"blazingly fast\", etc.\n\n## Coding style\n\n* Reduce nesting - i.e. prefer early returns over an `else` block, as per https://danp.net/posts/reducing-go-nesting/ or https://go.dev/doc/effective_go#if\n* Use line breaks to separate \"paragraphs\" of code - don't use line breaks in between lines, or at the start/end of functions etc.\n* Use the `xc fmt` and `xc lint` build tasks to format and lint code before committing.\n* Don't use unnecessary comments that explain what the code does.\n* If comments are used, ensure that they are full sentences, and use proper punctuation, including ending with a full stop.\n* Don't write comments after the end of keywords, e.g. `continue // Only process pairs`\n\n## Tests\n\n* Tests for generated code are in the `./generator` directory. Each test is in a subdirectory.\n* Tests for the templ CLI are in the `./cmd/templ` directory.\n* Tests for the templ runtime are in the root directory.\n* Tests for formatting templ files are in `./parser/v2/formattestdata` - it uses txtar to store tests.\n* The `htmldiff` library does not take whitespace into account, so cannot be used to test output whitespace handling.\n* Don't attempt to run tests individually, use the `xc test` task to run all tests, because it regenerates templates, and there's minimal performance penalty due to Go's test caching.\n\n## Moving and renaming files\n\n* templ files have the `.templ` extension.\n* If a `project.templ` file is created, after generation a `project_templ.go` file will be created.\n* If a `project.templ` file is renamed, you must also rename the generated `project_templ.go` file.\n* If a `project.templ` file is moved, you must also move the generated `project_templ.go` file.\n* If a `project.templ` file is deleted, you must also delete the generated `project_templ.go` file.\n\n# Files\n\n* Don't attempt to create helper or utility tests in the `./tmp` or `/tmp` directory. Create unit tests in the relevant directory instead."
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\npermissions:\n  contents: read\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: nixbuild/nix-quick-install-action@v30\n        with:\n          github_access_token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Restore and save Nix store\n        uses: nix-community/cache-nix-action@v6\n        with:\n          primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}\n          gc-max-store-size-linux: 1G\n          purge: true\n          purge-prefixes: nix-${{ runner.os }}-\n          purge-primary-key: never\n\n      - name: Test\n        run: nix develop --command xc test-cover\n\n      - name: Upload coverage artifact\n        if: github.event_name == 'push'\n        uses: actions/upload-artifact@v4\n        with:\n          name: coverage\n          path: coverage.out\n      \n      - name: Build\n        run: nix build\n\n  update-coverage:\n    if: github.event_name == 'push'\n    needs: build\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Download coverage\n        uses: actions/download-artifact@v4\n        with:\n          name: coverage\n\n      - name: Update coverage report\n        uses: ncruces/go-coverage-report@57ac6f0f19874f7afbab596105154f08004f482e\n        with:\n          coverage-file: coverage.out\n          report: 'true'\n          chart: 'true'\n          reuse-go: 'true'\n\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: nixbuild/nix-quick-install-action@v30\n        with:\n          github_access_token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Restore and save Nix store\n        uses: nix-community/cache-nix-action@v6\n        with:\n          primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}\n          gc-max-store-size-linux: 1G\n          purge: true\n          purge-prefixes: nix-${{ runner.os }}-\n          purge-primary-key: never\n\n      - name: Lint\n        run: nix develop --command xc lint\n\n  ensure-generated:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: nixbuild/nix-quick-install-action@v30\n        with:\n          github_access_token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Restore and save Nix store\n        uses: nix-community/cache-nix-action@v6\n        with:\n          primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}\n          gc-max-store-size-linux: 1G\n          purge: true\n          purge-prefixes: nix-${{ runner.os }}-\n          purge-primary-key: never\n\n      - name: Generate\n        run: nix develop --command xc ensure-generated\n\n  ensure-fmt:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: nixbuild/nix-quick-install-action@v30\n        with:\n          github_access_token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Restore and save Nix store\n        uses: nix-community/cache-nix-action@v6\n        with:\n          primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}\n          gc-max-store-size-linux: 1G\n          purge: true\n          purge-prefixes: nix-${{ runner.os }}-\n          purge-primary-key: never\n\n      - name: Fmt\n        run: nix develop --command xc fmt\n\n      - name: Ensure clean\n        run: git diff --exit-code\n"
  },
  {
    "path": ".github/workflows/docs.yaml",
    "content": "name: Deploy Docs\n\non:\n  release:\n    types: [published]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  pages: write\n  id-token: write\n\nconcurrency:\n  group: \"pages\"\n  cancel-in-progress: false\n\ndefaults:\n  run:\n    shell: bash\n\njobs:\n  build-docs:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          submodules: recursive\n          fetch-depth: 0\n      - name: Setup Pages\n        id: pages\n        uses: actions/configure-pages@v5\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n          cache: npm\n          cache-dependency-path: \"./docs/package-lock.json\"\n      - name: Install Node.js dependencies\n        run: |\n          cd docs\n          npm ci\n      - name: Build\n        run: |\n          cd docs\n          npm run build\n      - name: Upload artifact\n        uses: actions/upload-pages-artifact@v3\n        with:\n          path: ./docs/build\n\n  deploy-docs:\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    runs-on: ubuntu-latest\n    needs: build-docs\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n"
  },
  {
    "path": ".github/workflows/flakehub-publish-tagged.yml",
    "content": "name: \"Publish tags to FlakeHub\"\non:\n  push:\n    tags:\n      - \"v?[0-9]+.[0-9]+.[0-9]+*\"\n  workflow_dispatch:\n    inputs:\n      tag:\n        description: \"The existing tag to publish to FlakeHub\"\n        type: \"string\"\n        required: true\njobs:\n  flakehub-publish:\n    runs-on: \"ubuntu-latest\"\n    permissions:\n      id-token: \"write\"\n      contents: \"read\"\n    steps:\n      - uses: \"actions/checkout@v4\"\n        with:\n          ref: \"${{ (inputs.tag != null) && format('refs/tags/{0}', inputs.tag) || '' }}\"\n      - uses: \"DeterminateSystems/determinate-nix-action@v3\"\n      - uses: \"DeterminateSystems/flakehub-push@main\"\n        with:\n          visibility: \"public\"\n          name: \"a-h/templ\"\n          tag: \"${{ inputs.tag }}\"\n          include-output-paths: true\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  push:\n    tags:\n      - 'v*'\n  workflow_dispatch:\n\npermissions:\n   contents: write\n   packages: write\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-go@v5\n        with:\n          go-version: 1.23\n          cache: true\n      - uses: ko-build/setup-ko@v0.7\n      - uses: sigstore/cosign-installer@v3.7.0\n        with:\n          cosign-release: v2.2.3\n      - uses: goreleaser/goreleaser-action@v5\n        with:\n          version: v1.24.0\n          args: release --clean\n        env:\n          GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'\n          COSIGN_PASSWORD: '${{ secrets.COSIGN_PASSWORD }}'\n          COSIGN_PRIVATE_KEY: '${{ secrets.COSIGN_PRIVATE_KEY }}'\n          COSIGN_PUBLIC_KEY: '${{ secrets.COSIGN_PUBLIC_KEY }}'\n"
  },
  {
    "path": ".gitignore",
    "content": "# Output.\ncmd/templ/templ\n\n# Logs.\ncmd/templ/lspcmd/*log.txt\n\n# Go code coverage.\ncoverage.out\ncoverage\n\n# Mac filesystem jank.\n.DS_Store\n\n# Docusaurus.\ndocs/build/\ndocs/resources/_gen/\nnode_modules/\ndist/\n\n# Nix artifacts.\nresult\n\n# Editors\n## nvim\n.null-ls*\n# vscode\n.vscode/\n\n# Go workspace.\ngo.work\n\n# direnv\n.direnv\n\n# templ txt files.\n*_templ.txt\n\n# Example output binaries.\n/examples/integration-gin/integration-gin\n/examples/integration-echo/integration-echo\n"
  },
  {
    "path": ".goreleaser.yaml",
    "content": "builds:\n  - env:\n      - CGO_ENABLED=0\n    dir: cmd/templ\n    mod_timestamp: '{{ .CommitTimestamp }}'\n    flags:\n      - -trimpath\n    ldflags:\n      - -s -w\n    goos:\n      - linux\n      - windows\n      - darwin\n\nchecksum:\n  name_template: 'checksums.txt'\n\nsigns:\n  - id: checksums\n    cmd: cosign\n    stdin: '{{ .Env.COSIGN_PASSWORD }}'\n    output: true\n    artifacts: checksum\n    args:\n      - sign-blob\n      - --yes\n      - --key\n      - env://COSIGN_PRIVATE_KEY\n      - '--output-certificate=${certificate}'\n      - '--output-signature=${signature}'\n      - '${artifact}'\n\narchives:\n  - format: tar.gz\n    name_template: >-\n      {{ .ProjectName }}_\n      {{- title .Os }}_\n      {{- if eq .Arch \"amd64\" }}x86_64\n      {{- else if eq .Arch \"386\" }}i386\n      {{- else }}{{ .Arch }}{{ end }}\n      {{- if .Arm }}v{{ .Arm }}{{ end }}\n\nkos:\n  - repository: ghcr.io/a-h/templ\n    platforms:\n    - linux/amd64\n    - linux/arm64\n    tags:\n    - latest\n    - '{{.Tag}}'\n    bare: true\n\ndocker_signs:\n  - cmd: cosign\n    artifacts: all\n    output: true\n    args:\n      - sign\n      - --yes\n      - --key\n      - env://COSIGN_PRIVATE_KEY\n      - '${artifact}'\n\nsnapshot:\n  name_template: \"{{ incpatch .Version }}-next\"\n\nchangelog:\n  sort: asc\n  filters:\n    exclude:\n      - '^docs:'\n      - '^test:'\n"
  },
  {
    "path": ".ignore",
    "content": "*_templ.go\nexamples/integration-ct/static/index.js\nexamples/counter/assets/css/bulma.*\nexamples/counter/assets/js/htmx.min.js\nexamples/counter-basic/assets/css/bulma.*\nexamples/typescript/assets/index.js\npackage-lock.json\ngo.sum\ndocs/static/llms.md\n"
  },
  {
    "path": ".version",
    "content": "0.3.1002"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\nadrianhesketh@hushail.com.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to templ\n\n## Vision\n\nEnable Go developers to build strongly typed, component-based HTML user interfaces with first-class developer tooling, and a short learning curve.\n\n## Come up with a design and share it\n\nBefore starting work on any major pull requests or code changes, start a discussion at https://github.com/a-h/templ/discussions or raise an issue.\n\nWe don't want you to spend time on a PR or feature that ultimately doesn't get merged because it doesn't fit with the project goals, or the design doesn't work for some reason.\n\nFor issues, it really helps if you provide a reproduction repo, or can create a failing unit test to describe the behaviour.\n\nIn designs, we need to consider:\n\n* Backwards compatibility - Not changing the public API between releases, introducing gradual deprecation - don't break people's code.\n* Correctness over time - How can we reduce the risk of defects both now, and in future releases?\n* Threat model - How could each change be used to inject vulnerabilities into web pages?\n* Go version - We target the oldest supported version of Go as per https://go.dev/doc/devel/release\n* Automatic migration - If we need to force through a change.\n* Compile time vs runtime errors - Prefer compile time.\n* Documentation - New features are only useful if people can understand the new feature, what would the documentation look like?\n* Examples - How will we demonstrate the feature?\n\n## Project structure\n\ntempl is structured into a few areas:\n\n### Parser `./parser`\n\nThe parser directory currently contains both v1 and v2 parsers.\n\nThe v1 parser is not maintained, it's only used to migrate v1 code over to the v2 syntax.\n\nThe parser is responsible for parsing templ files into an object model. The types that make up the object model are in `types.go`. Automatic formatting of the types is tested in `types_test.go`.\n\nA templ file is parsed into the `TemplateFile` struct object model.\n\n```go\ntype TemplateFile struct {\n\t// Header contains comments or whitespace at the top of the file.\n\tHeader []GoExpression\n\t// Package expression.\n\tPackage Package\n\t// Nodes in the file.\n\tNodes []TemplateFileNode\n}\n```\n\nParsers are individually tested using two types of unit test.\n\nOne test covers the successful parsing of text into an object. For example, the `HTMLCommentParser` test checks for successful patterns.\n\n```go\nfunc TestHTMLCommentParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected HTMLComment\n\t}{\n\t\t{\n\t\t\tname:  \"comment - single line\",\n\t\t\tinput: `<!-- single line comment -->`,\n\t\t\texpected: HTMLComment{\n\t\t\t\tContents: \" single line comment \",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"comment - no whitespace\",\n\t\t\tinput: `<!--no whitespace between sequence open and close-->`,\n\t\t\texpected: HTMLComment{\n\t\t\t\tContents: \"no whitespace between sequence open and close\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"comment - multiline\",\n\t\t\tinput: `<!-- multiline\n\t\t\t\t\t\t\t\tcomment\n\t\t\t\t\t-->`,\n\t\t\texpected: HTMLComment{\n\t\t\t\tContents: ` multiline\n\t\t\t\t\t\t\t\tcomment\n\t\t\t\t\t`,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"comment - with tag\",\n\t\t\tinput: `<!-- <p class=\"test\">tag</p> -->`,\n\t\t\texpected: HTMLComment{\n\t\t\t\tContents: ` <p class=\"test\">tag</p> `,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"comments can contain tags\",\n\t\t\tinput: `<!-- <div> hello world </div> -->`,\n\t\t\texpected: HTMLComment{\n\t\t\t\tContents: ` <div> hello world </div> `,\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := htmlComment.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Errorf(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n```\n\nAlongside each success test, is a similar test to check that invalid syntax is detected.\n\n```go\nfunc TestHTMLCommentParserErrors(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected error\n\t}{\n\t\t{\n\t\t\tname:  \"unclosed HTML comment\",\n\t\t\tinput: `<!-- unclosed HTML comment`,\n\t\t\texpected: parse.Error(\"expected end comment literal '-->' not found\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 26,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   26,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tname:  \"comment in comment\",\n\t\t\tinput: `<!-- <-- other --> -->`,\n\t\t\texpected: parse.Error(\"comment contains invalid sequence '--'\", parse.Position{\n\t\t\t\tIndex: 8,\n\t\t\t\tLine:  0,\n\t\t\t\tCol:   8,\n\t\t\t}),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, _, err := htmlComment.Parse(input)\n\t\t\tif diff := cmp.Diff(tt.expected, err); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n```\n\n### Generator\n\nThe generator takes the object model and writes out Go code that produces the expected output. Any changes to Go code output by templ are made in this area.\n\nTesting of the generator is carried out by creating a templ file, and a matching expected output file.\n\nFor example, `./generator/test-a-href` contains a templ file of:\n\n```templ\npackage testahref\n\ntempl render() {\n\t<a href=\"javascript:alert(&#39;unaffected&#39;);\">Ignored</a>\n\t<a href={ templ.URL(\"javascript:alert('should be sanitized')\") }>Sanitized</a>\n\t<a href={ templ.SafeURL(\"javascript:alert('should not be sanitized')\") }>Unsanitized</a>\n}\n```\n\nIt also contains an expected output file.\n\n```html\n<a href=\"javascript:alert(&#39;unaffected&#39;);\">Ignored</a>\n<a href=\"about:invalid#TemplFailedSanitizationURL\">Sanitized</a>\n<a href=\"javascript:alert(&#39;should not be sanitized&#39;)\">Unsanitized</a>\n```\n\nThese tests contribute towards the code coverage metrics by building an instrumented test CLI program. See the `test-cover` task in the `README.md` file.\n\n### CLI\n\nThe command line interface for templ is used to generate Go code from templ files, format templ files, and run the LSP.\n\nThe code for this is at `./cmd/templ`.\n\nTesting of the templ command line is done with unit tests to check the argument parsing.\n\nThe `templ generate` command is tested by generating templ files in the project, and testing that the expected output HTML is present.\n\n### Runtime\n\nThe runtime is used by generated code, and by template authors, to serve template content over HTTP, and to carry out various operations.\n\nIt is in the root directory of the project at `./runtime.go`. The runtime is unit tested, as well as being tested as part of the `generate` tests.\n\n### LSP\n\nThe LSP is structured within the command line interface, and proxies commands through to the `gopls` LSP.\n\n### Docs\n\nThe docs are a Docusaurus project at `./docs`.\n\n## Coding\n\n### Build tasks\n\ntempl uses the `xc` task runner - https://github.com/joerdav/xc\n\nIf you run `xc` you can get see a list of the development tasks that can be run, or you can read the `README.md` file and see the `Tasks` section.\n\nThe most useful tasks for local development are:\n\n* `install-snapshot` - this builds the templ CLI and installs it into `~/bin`. Ensure that this is in your path.\n* `test` - this regenerates all templates, and runs the unit tests.\n* `fmt` - run the `gofmt` tool to format all Go code.\n* `lint` - run the same linting as run in the CI process.\n* `docs-run` - run the Docusaurus documentation site.\n\n### Commit messages\n\nThe project using https://www.conventionalcommits.org/en/v1.0.0/\n\nExamples:\n\n* `feat: support Go comments in templates, fixes #234\"`\n\n### Coding style\n\n* Reduce nesting - i.e. prefer early returns over an `else` block, as per https://danp.net/posts/reducing-go-nesting/ or https://go.dev/doc/effective_go#if\n* Use line breaks to separate \"paragraphs\" of code - don't use line breaks in between lines, or at the start/end of functions etc.\n* Use the `fmt` and `lint` build tasks to format and lint your code before submitting a PR.\n\n### LLM instructions\n\nSee additional coding standards at `.github/copilot-instructions.md`\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Adrian Hesketh\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": "README.md",
    "content": "![templ](https://github.com/a-h/templ/raw/main/templ.png)\n\n## An HTML templating language for Go that has great developer tooling.\n\n![templ](ide-demo.gif)\n\n\n## Documentation\n\nSee user documentation at https://templ.guide\n\n<p align=\"center\">\n<a href=\"https://pkg.go.dev/github.com/a-h/templ\"><img src=\"https://pkg.go.dev/badge/github.com/a-h/templ.svg\" alt=\"Go Reference\" /></a>\n<a href=\"https://xcfile.dev\"><img src=\"https://xcfile.dev/badge.svg\" alt=\"xc compatible\" /></a>\n<a href=\"https://raw.githack.com/wiki/a-h/templ/coverage.html\"><img src=\"https://github.com/a-h/templ/wiki/coverage.svg\" alt=\"Go Coverage\" /></a>\n<a href=\"https://goreportcard.com/report/github.com/a-h/templ\"><img src=\"https://goreportcard.com/badge/github.com/a-h/templ\" alt=\"Go Report Card\" /></a>\n</p>\n\n## Tasks\n\n### version-set\n\nSet the version of templ to the current version.\n\n```sh\nversion set --template=\"0.3.%d\"\n```\n\n### build\n\nBuild a local version.\n\n```sh\nversion set --template=\"0.3.%d\"\ncd cmd/templ\ngo build\n```\n\n### install-snapshot\n\nBuild and install current version.\n\n```sh\n# Remove templ from the non-standard ~/bin/templ path\n# that this command previously used.\nrm -f ~/bin/templ\n# Clear LSP logs.\nrm -f cmd/templ/lspcmd/*.txt\n# Update version.\nversion set --template=\"0.3.%d\"\n# Install to $GOPATH/bin or $HOME/go/bin\ncd cmd/templ && go install\n```\n\n### build-snapshot\n\nUse goreleaser to build the command line binary using goreleaser.\n\n```sh\ngoreleaser build --snapshot --clean\n```\n\n### generate\n\nRun templ generate using local version.\n\n```sh\ngo run ./cmd/templ generate -include-version=false\n```\n\n### test\n\nRun Go tests.\n\n```sh\nversion set --template=\"0.3.%d\"\ngo run ./cmd/templ generate -include-version=false\ngo test ./...\n```\n\n### test-short\n\nRun Go tests.\n\n```sh\nversion set --template=\"0.3.%d\"\ngo run ./cmd/templ generate -include-version=false\ngo test ./... -short\n```\n\n### test-cover\n\nRun Go tests.\n\n```sh\n# Create test profile directories.\nmkdir -p coverage/fmt\nmkdir -p coverage/generate\nmkdir -p coverage/version\nmkdir -p coverage/unit\n# Build the test binary.\ngo build -cover -o ./coverage/templ-cover ./cmd/templ\n# Run the covered generate command.\nGOCOVERDIR=coverage/fmt ./coverage/templ-cover fmt .\nGOCOVERDIR=coverage/generate ./coverage/templ-cover generate -include-version=false\nGOCOVERDIR=coverage/version ./coverage/templ-cover version\n# Run the unit tests.\ngo test -cover ./... -coverpkg ./... -args -test.gocoverdir=\"$PWD/coverage/unit\"\n# Display the combined percentage.\ngo tool covdata percent -i=./coverage/fmt,./coverage/generate,./coverage/version,./coverage/unit\n# Generate a text coverage profile for tooling to use.\ngo tool covdata textfmt -i=./coverage/fmt,./coverage/generate,./coverage/version,./coverage/unit -o coverage.out\n# Print total\ngo tool cover -func coverage.out | grep total\n```\n\n### test-cover-watch\n\ninteractive: true\n\n```sh\ngotestsum --watch -- -coverprofile=coverage.out\n```\n\n### test-fuzz\n\n```sh\n./parser/v2/fuzz.sh\n./parser/v2/goexpression/fuzz.sh\n```\n\n### benchmark\n\nRun benchmarks.\n\n```sh\ngo run ./cmd/templ generate -include-version=false && go test ./... -bench=. -benchmem\n```\n\n### fmt\n\nFormat all Go and templ code.\n\n```sh\ngofmt -s -w .\ngo run ./cmd/templ fmt .\n```\n\n### lint\n\nRun the lint operations that are run as part of the CI.\n\n```sh\ngolangci-lint run --verbose\n```\n\n### ensure-generated\n\nEnsure that templ files have been generated with the local version of templ, and that those files have been added to git.\n\nRequires: generate\n\n```sh\ngit diff --exit-code\n```\n\n### push-release-tag\n\nPush a semantic version number to GitHub to trigger the release process.\n\n```sh\nversion push --template=\"0.3.%d\" --prefix=\"v\"\n```\n\n### docs-run\n\nRun the development server.\n\nDirectory: docs\n\n```sh\nnpm run start\n```\n\n### docs-build\n\nBuild production docs site.\n\nDirectory: docs\n\n```sh\nnpm run build\n```\n\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nThe latest version of templ is supported.\n\n## Reporting a Vulnerability\n\nUse the \"Security\" tab in GitHub and fill out the \"Report a vulnerability\" form.\n"
  },
  {
    "path": "benchmarks/react/.gitignore",
    "content": "index.js\nnode_modules\n\n"
  },
  {
    "path": "benchmarks/react/README.md",
    "content": "# React benchmark\n\n## Tasks\n\n### install\n\n```\nnpm i\n```\n\n### build\n\n```sh\nnpm run build\n```\n\n### run\n\nrequires: build\n\n```sh\nnpm start\n```\n"
  },
  {
    "path": "benchmarks/react/package.json",
    "content": "{\n  \"name\": \"react-benchmark\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"./src/index.jsx\",\n  \"scripts\": {\n    \"build\": \"esbuild ./src/index.jsx --bundle --outfile=index.js\",\n    \"start\": \"node index.js\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"benchmark\": \"^2.1.4\",\n    \"esbuild\": \"0.25.0\",\n    \"microtime\": \"^3.0.0\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\"\n  }\n}\n"
  },
  {
    "path": "benchmarks/react/src/index.jsx",
    "content": "import * as React from 'react'\nimport * as Server from 'react-dom/server'\nimport Benchmark from 'benchmark';\n\nconst component = (p) =>\n        <div>\n                <h1>{p.Name}</h1>\n                <div style={{ fontFamily: \"sans-serif\" }} id=\"test\" data-contents=\"something with &#34;quotes&#34; and a &lt;tag&gt;\">\n                        <div>email:<a href=\"mailto: luiz@example.com\">luiz@example.com</a></div>\n                </div>\n                <hr noshade /><hr optionA optionB optionC=\"other\" /><hr noshade />\n        </div>;\n\nconst p = {\n        Name: \"Luiz Bonfa\",\n        Email: \"luiz@example.com\",\n};\n\n// Benchmark.\n// Outputs...\n// Render test x 114,131 ops/sec ±0.27% (97 runs sampled)\n// There are 1,000,000,000 nanoseconds in a second.\n// 1,000,000,000ns / 114,131 ops = 8,757.5 ns per operation.\n// The templ equivalent is 340 ns per operation.\nconst suite = new Benchmark.Suite;\n\nconst test = suite.add('Render test',\n        () => Server.renderToString(component(p)))\n\ntest.on('cycle', (event) => {\n        console.log(String(event.target));\n});\n\ntest.run();\n"
  },
  {
    "path": "benchmarks/templ/README.md",
    "content": "# templ benchmark\n\nUsed to test code generation strategies for improvements to render time.\n\n## Tasks\n\n### run\n\n```\ngo test -bench .\n```\n\n## Results as of 2023-08-17\n\n```\ngo test -bench .\ngoos: darwin\ngoarch: arm64\npkg: github.com/a-h/templ/benchmarks/templ\nBenchmarkTempl-10                3291883               369.1 ns/op           536 B/op          6 allocs/op\nBenchmarkGoTemplate-10            481052              2475 ns/op            1400 B/op         38 allocs/op\nBenchmarkIOWriteString-10       20353198                56.64 ns/op          320 B/op          1 allocs/op\nPASS\nok      github.com/a-h/templ/benchmarks/templ   4.650s\n```\n\nReact comes in at 1,000,000,000ns / 114,131 ops/s = 8,757.5 ns per operation.\n"
  },
  {
    "path": "benchmarks/templ/data.go",
    "content": "package testhtml\n\ntype Person struct {\n\tName  string\n\tEmail string\n}\n"
  },
  {
    "path": "benchmarks/templ/render_test.go",
    "content": "package testhtml\n\nimport (\n\t\"context\"\n\t\"html/template\"\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t_ \"embed\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\nfunc BenchmarkTemplRender(b *testing.B) {\n\tb.ReportAllocs()\n\tt := Render(Person{\n\t\tName:  \"Luiz Bonfa\",\n\t\tEmail: \"luiz@example.com\",\n\t})\n\n\tw := new(strings.Builder)\n\tfor range b.N {\n\t\terr := t.Render(context.Background(), w)\n\t\tif err != nil {\n\t\t\tb.Errorf(\"failed to render: %v\", err)\n\t\t}\n\t\tw.Reset()\n\t}\n}\n\n//go:embed template.templ\nvar parserBenchmarkTemplate string\n\nfunc BenchmarkTemplParser(b *testing.B) {\n\tfor range b.N {\n\t\ttf, err := parser.ParseString(parserBenchmarkTemplate)\n\t\tif err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t\tif tf.Package.Expression.Value == \"\" {\n\t\t\tb.Fatal(\"unexpected nil template\")\n\t\t}\n\t}\n}\n\nvar goTemplate = template.Must(template.New(\"example\").Parse(`<div>\n\t<h1>{{.Name}}</h1>\n\t<div style=\"font-family: &#39;sans-serif&#39;\" id=\"test\" data-contents=\"something with &#34;quotes&#34; and a &lt;tag&gt;\">\n\t\t<div>\n\t\t\temail:<a href=\"mailto: {{.Email}}\">{{.Email}}</a></div>\n\t\t</div>\n\t</div>\n\t<hr noshade>\n\t<hr optionA optionB optionC=\"other\">\n\t<hr noshade>\n`))\n\nfunc BenchmarkGoTemplateRender(b *testing.B) {\n\tw := new(strings.Builder)\n\tperson := Person{\n\t\tName:  \"Luiz Bonfa\",\n\t\tEmail: \"luiz@exapmle.com\",\n\t}\n\tb.ReportAllocs()\n\tfor range b.N {\n\t\terr := goTemplate.Execute(w, person)\n\t\tif err != nil {\n\t\t\tb.Errorf(\"failed to render: %v\", err)\n\t\t}\n\t\tw.Reset()\n\t}\n}\n\nconst html = `<div><h1>Luiz Bonfa</h1><div style=\"font-family: &#39;sans-serif&#39;\" id=\"test\" data-contents=\"something with &#34;quotes&#34; and a &lt;tag&gt;\"><div>email:<a href=\"mailto: luiz@example.com\">luiz@example.com</a></div></div></div><hr noshade><hr optionA optionB optionC=\"other\"><hr noshade>`\n\nfunc BenchmarkIOWriteString(b *testing.B) {\n\tb.ReportAllocs()\n\tw := new(strings.Builder)\n\tfor range b.N {\n\t\t_, err := io.WriteString(w, html)\n\t\tif err != nil {\n\t\t\tb.Errorf(\"failed to render: %v\", err)\n\t\t}\n\t\tw.Reset()\n\t}\n}\n"
  },
  {
    "path": "benchmarks/templ/template.templ",
    "content": "package testhtml\n\ntempl Render(p Person) {\n\t<div>\n\t\t<h1>{ p.Name }</h1>\n\t\t<div style=\"font-family: 'sans-serif'\" id=\"test\" data-contents={ `something with \"quotes\" and a <tag>` }>\n\t\t\t<div>email:<a href={ templ.URL(\"mailto: \" + p.Email) }>{ p.Email }</a></div>\n\t\t</div>\n\t</div>\n\t<hr noshade?={ true }/>\n\t<hr optionA optionB?={ true } optionC=\"other\" optionD?={ false }/>\n\t<hr noshade/>\n}\n"
  },
  {
    "path": "benchmarks/templ/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testhtml\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Render(p Person) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div><h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `benchmarks/templ/template.templ`, Line: 5, Col: 14}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</h1><div style=\\\"font-family: 'sans-serif'\\\" id=\\\"test\\\" data-contents=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(`something with \"quotes\" and a <tag>`)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `benchmarks/templ/template.templ`, Line: 6, Col: 104}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\"><div>email:<a href=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 templ.SafeURL\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(\"mailto: \" + p.Email))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `benchmarks/templ/template.templ`, Line: 7, Col: 55}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.Email)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `benchmarks/templ/template.templ`, Line: 7, Col: 67}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</a></div></div></div><hr\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \" noshade\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"><hr optionA\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \" optionB\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \" optionC=\\\"other\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif false {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \" optionD\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"><hr noshade>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "cfg/cfg.go",
    "content": "// This package is inspired by the GOEXPERIMENT approach of allowing feature flags for experimenting with breaking changes.\npackage cfg\n\nimport (\n\t\"os\"\n\t\"strings\"\n)\n\ntype Flags struct{}\n\nvar Experiment = parse()\n\nfunc parse() *Flags {\n\tm := map[string]bool{}\n\tfor _, f := range strings.Split(os.Getenv(\"TEMPL_EXPERIMENT\"), \",\") {\n\t\tm[strings.ToLower(f)] = true\n\t}\n\n\treturn &Flags{}\n}\n"
  },
  {
    "path": "cmd/templ/fmtcmd/main.go",
    "content": "package fmtcmd\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/cmd/templ/processor\"\n\t\"github.com/a-h/templ/internal/format\"\n\t\"github.com/natefinch/atomic\"\n)\n\ntype Arguments struct {\n\tFailIfChanged    bool\n\tToStdout         bool\n\tStdinFilepath    string\n\tFiles            []string\n\tWorkerCount      int\n\tPrettierCommand  string\n\tPrettierRequired bool\n}\n\nfunc Run(log *slog.Logger, stdin io.Reader, stdout io.Writer, args Arguments) (err error) {\n\t// If no files are provided, read from stdin and write to stdout.\n\tformatterConfig := format.Config{\n\t\tPrettierCommand:  args.PrettierCommand,\n\t\tPrettierRequired: args.PrettierRequired,\n\t}\n\tif len(args.Files) == 0 {\n\t\tsrc, err := io.ReadAll(stdin)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read from stdin: %w\", err)\n\t\t}\n\t\tformatted, _, err := format.Templ(src, args.StdinFilepath, formatterConfig)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to format stdin: %w\", err)\n\t\t}\n\t\tif _, err = stdout.Write(formatted); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write to stdout: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n\t// If files are provided, process each file.\n\tprocess := func(fileName string) (error, bool) {\n\t\tsrc, err := os.ReadFile(fileName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read file %q: %w\", fileName, err), false\n\t\t}\n\t\tformatted, changed, err := format.Templ(src, fileName, formatterConfig)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to format file %q: %w\", fileName, err), false\n\t\t}\n\t\tif !changed && !args.ToStdout {\n\t\t\treturn nil, false\n\t\t}\n\t\tif args.ToStdout {\n\t\t\tif _, err := stdout.Write(formatted); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to write to stdout: %w\", err), false\n\t\t\t}\n\t\t\treturn nil, true\n\t\t}\n\t\tif err := atomic.WriteFile(fileName, bytes.NewBuffer(formatted)); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write file %q: %w\", fileName, err), false\n\t\t}\n\t\treturn nil, true\n\t}\n\tdir := args.Files[0]\n\treturn NewFormatter(log, dir, process, args.WorkerCount, args.FailIfChanged).Run()\n}\n\ntype Formatter struct {\n\tLog          *slog.Logger\n\tDir          string\n\tProcess      func(fileName string) (error, bool)\n\tWorkerCount  int\n\tFailIfChange bool\n}\n\nfunc NewFormatter(log *slog.Logger, dir string, process func(fileName string) (error, bool), workerCount int, failIfChange bool) *Formatter {\n\tf := &Formatter{\n\t\tLog:          log,\n\t\tDir:          dir,\n\t\tProcess:      process,\n\t\tWorkerCount:  workerCount,\n\t\tFailIfChange: failIfChange,\n\t}\n\tif f.WorkerCount == 0 {\n\t\tf.WorkerCount = runtime.NumCPU()\n\t}\n\treturn f\n}\n\nfunc (f *Formatter) Run() (err error) {\n\tvar errs []error\n\tchangesMade := 0\n\tstart := time.Now()\n\tresults := make(chan processor.Result)\n\tf.Log.Debug(\"Walking directory\", slog.String(\"path\", f.Dir))\n\tgo processor.Process(f.Dir, f.Process, f.WorkerCount, results)\n\tvar successCount, errorCount int\n\tfor r := range results {\n\t\tif r.ChangesMade {\n\t\t\tchangesMade += 1\n\t\t}\n\t\tif r.Error != nil {\n\t\t\tf.Log.Error(r.FileName, slog.Any(\"error\", r.Error))\n\t\t\terrorCount++\n\t\t\terrs = append(errs, r.Error)\n\t\t\tcontinue\n\t\t}\n\t\tf.Log.Debug(r.FileName, slog.Duration(\"duration\", r.Duration))\n\t\tsuccessCount++\n\t}\n\n\tif f.FailIfChange && changesMade > 0 {\n\t\tf.Log.Error(\"Templates were valid but not properly formatted\", slog.Int(\"count\", successCount+errorCount), slog.Int(\"changed\", changesMade), slog.Int(\"errors\", errorCount), slog.Duration(\"duration\", time.Since(start)))\n\t\treturn fmt.Errorf(\"templates were not formatted properly\")\n\t}\n\n\tf.Log.Info(\"Format Complete\", slog.Int(\"count\", successCount+errorCount), slog.Int(\"errors\", errorCount), slog.Int(\"changed\", changesMade), slog.Duration(\"duration\", time.Since(start)))\n\n\tif err = errors.Join(errs...); err != nil {\n\t\treturn fmt.Errorf(\"formatting failed: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/templ/fmtcmd/main_test.go",
    "content": "package fmtcmd\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/tools/txtar\"\n)\n\n//go:embed testdata.txtar\nvar testDataTxTar []byte\n\ntype testProject struct {\n\tdir       string\n\tcleanup   func() error\n\ttestFiles map[string]testFile\n}\n\ntype testFile struct {\n\tname            string\n\tinput, expected string\n}\n\nfunc setupProjectDir() (tp testProject, err error) {\n\ttp.dir, err = os.MkdirTemp(\"\", \"fmtcmd_test_*\")\n\tif err != nil {\n\t\treturn tp, fmt.Errorf(\"failed to make test dir: %w\", err)\n\t}\n\ttp.testFiles = make(map[string]testFile)\n\ttestData := txtar.Parse(testDataTxTar)\n\tfor i := 0; i < len(testData.Files); i += 2 {\n\t\tfile := testData.Files[i]\n\t\terr = os.WriteFile(filepath.Join(tp.dir, file.Name), file.Data, 0660)\n\t\tif err != nil {\n\t\t\treturn tp, fmt.Errorf(\"failed to write file: %w\", err)\n\t\t}\n\t\ttp.testFiles[file.Name] = testFile{\n\t\t\tname:     filepath.Join(tp.dir, file.Name),\n\t\t\tinput:    string(file.Data),\n\t\t\texpected: string(testData.Files[i+1].Data),\n\t\t}\n\t}\n\ttp.cleanup = func() error {\n\t\tif err := os.RemoveAll(tp.dir); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to remove test directory %q: %w\", tp.dir, err)\n\t\t}\n\t\treturn nil\n\t}\n\treturn tp, nil\n}\n\nfunc TestFormat(t *testing.T) {\n\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\tt.Run(\"can format a single file from stdin to stdout\", func(t *testing.T) {\n\t\ttp, err := setupProjectDir()\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to setup project dir: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := tp.cleanup(); err != nil {\n\t\t\t\tt.Errorf(\"cleanup error: %v\", err)\n\t\t\t}\n\t\t}()\n\t\tstdin := strings.NewReader(tp.testFiles[\"a.templ\"].input)\n\t\tstdout := new(strings.Builder)\n\t\tif err = Run(log, stdin, stdout, Arguments{\n\t\t\tToStdout: true,\n\t\t}); err != nil {\n\t\t\tt.Fatalf(\"failed to run format command: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(tp.testFiles[\"a.templ\"].expected, stdout.String()); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"can process a single file to stdout\", func(t *testing.T) {\n\t\ttp, err := setupProjectDir()\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to setup project dir: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := tp.cleanup(); err != nil {\n\t\t\t\tt.Errorf(\"cleanup error: %v\", err)\n\t\t\t}\n\t\t}()\n\t\tstdout := new(strings.Builder)\n\t\tif err = Run(log, nil, stdout, Arguments{\n\t\t\tToStdout: true,\n\t\t\tFiles: []string{\n\t\t\t\ttp.testFiles[\"a.templ\"].name,\n\t\t\t},\n\t\t\tFailIfChanged: false,\n\t\t}); err != nil {\n\t\t\tt.Fatalf(\"failed to run format command: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(tp.testFiles[\"a.templ\"].expected, stdout.String()); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"can process a single file in place\", func(t *testing.T) {\n\t\ttp, err := setupProjectDir()\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to setup project dir: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := tp.cleanup(); err != nil {\n\t\t\t\tt.Errorf(\"cleanup error: %v\", err)\n\t\t\t}\n\t\t}()\n\t\tif err = Run(log, nil, nil, Arguments{\n\t\t\tFiles: []string{\n\t\t\t\ttp.testFiles[\"a.templ\"].name,\n\t\t\t},\n\t\t\tFailIfChanged: false,\n\t\t}); err != nil {\n\t\t\tt.Fatalf(\"failed to run format command: %v\", err)\n\t\t}\n\t\tdata, err := os.ReadFile(tp.testFiles[\"a.templ\"].name)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to read file: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(tp.testFiles[\"a.templ\"].expected, string(data)); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\n\tt.Run(\"fails when fail flag used and change occurs\", func(t *testing.T) {\n\t\ttp, err := setupProjectDir()\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to setup project dir: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := tp.cleanup(); err != nil {\n\t\t\t\tt.Errorf(\"cleanup error: %v\", err)\n\t\t\t}\n\t\t}()\n\t\tif err = Run(log, nil, nil, Arguments{\n\t\t\tFiles: []string{\n\t\t\t\ttp.testFiles[\"a.templ\"].name,\n\t\t\t},\n\t\t\tFailIfChanged: true,\n\t\t}); err == nil {\n\t\t\tt.Fatal(\"command should have exited with an error and did not\")\n\t\t}\n\t\tdata, err := os.ReadFile(tp.testFiles[\"a.templ\"].name)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to read file: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(tp.testFiles[\"a.templ\"].expected, string(data)); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\n\tt.Run(\"passes when fail flag used and no change occurs\", func(t *testing.T) {\n\t\ttp, err := setupProjectDir()\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to setup project dir: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := tp.cleanup(); err != nil {\n\t\t\t\tt.Errorf(\"cleanup error: %v\", err)\n\t\t\t}\n\t\t}()\n\t\tif err = Run(log, nil, nil, Arguments{\n\t\t\tFiles: []string{\n\t\t\t\ttp.testFiles[\"c.templ\"].name,\n\t\t\t},\n\t\t\tFailIfChanged: true,\n\t\t}); err != nil {\n\t\t\tt.Fatalf(\"failed to run format command: %v\", err)\n\t\t}\n\t\tdata, err := os.ReadFile(tp.testFiles[\"c.templ\"].name)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to read file: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(tp.testFiles[\"c.templ\"].expected, string(data)); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "cmd/templ/fmtcmd/testdata.txtar",
    "content": "-- a.templ --\npackage test\n\ntempl a() {\n\t<div><p class={templ.Class(\"mapped\")}>A\n</p></div>\n}\n-- a.templ --\npackage test\n\ntempl a() {\n\t<div>\n\t\t<p class={ templ.Class(\"mapped\") }>\n\t\t\tA\n\t\t</p>\n\t</div>\n}\n-- b.templ --\npackage test\n\ntempl b() {\n\t<div><p>B\n</p></div>\n}\n-- b.templ --\npackage test\n\ntempl b() {\n\t<div>\n\t\t<p>\n\t\t\tB\n\t\t</p>\n\t</div>\n}\n-- c.templ --\npackage test\n\ntempl c() {\n\t<div>\n\t\t<p>\n\t\t\tC\n\t\t</p>\n\t</div>\n}\n-- c.templ --\npackage test\n\ntempl c() {\n\t<div>\n\t\t<p>\n\t\t\tC\n\t\t</p>\n\t</div>\n}\n-- d.templ --\npackage test\n\ntempl c(s string) {\n  <div s= {s}/>\n}\n-- d.templ --\npackage test\n\ntempl c(s string) {\n  <div s={ s }/>\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/cmd.go",
    "content": "package generatecmd\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/internal/skipdir\"\n\ttemplruntime \"github.com/a-h/templ/runtime\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/modcheck\"\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/proxy\"\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/run\"\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/watcher\"\n\t\"github.com/a-h/templ/generator\"\n\t\"github.com/cenkalti/backoff/v4\"\n\t\"github.com/cli/browser\"\n\t\"github.com/fsnotify/fsnotify\"\n)\n\nfunc NewGenerate(log *slog.Logger, args Arguments) (g *Generate, err error) {\n\tg = &Generate{\n\t\tLog:  log,\n\t\tArgs: args,\n\t}\n\treturn g, nil\n}\n\ntype Generate struct {\n\tLog  *slog.Logger\n\tArgs Arguments\n}\n\ntype GenerationEvent struct {\n\tEvent                fsnotify.Event\n\tWatchedFileUpdated   bool\n\tTemplFileTextUpdated bool\n\tTemplFileGoUpdated   bool\n}\n\nfunc (cmd Generate) Run(ctx context.Context) (err error) {\n\tif cmd.Args.NotifyProxy {\n\t\treturn proxy.NotifyProxy(cmd.Args.ProxyBind, cmd.Args.ProxyPort)\n\t}\n\tif cmd.Args.PPROFPort > 0 {\n\t\tgo func() {\n\t\t\t_ = http.ListenAndServe(fmt.Sprintf(\"localhost:%d\", cmd.Args.PPROFPort), nil)\n\t\t}()\n\t}\n\n\t// Use absolute path.\n\tif !path.IsAbs(cmd.Args.Path) {\n\t\tcmd.Args.Path, err = filepath.Abs(cmd.Args.Path)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get absolute path: %w\", err)\n\t\t}\n\t}\n\n\t// Configure generator.\n\tvar opts []generator.GenerateOpt\n\tif cmd.Args.IncludeVersion {\n\t\topts = append(opts, generator.WithVersion(templ.Version()))\n\t}\n\tif cmd.Args.IncludeTimestamp {\n\t\topts = append(opts, generator.WithTimestamp(time.Now()))\n\t}\n\n\t// Check the version of the templ module.\n\tif err := modcheck.Check(cmd.Args.Path); err != nil {\n\t\tcmd.Log.Warn(\"templ version check: \" + err.Error())\n\t}\n\n\tcmd.Log.Debug(\"Creating filesystem event handler\")\n\tfseh := NewFSEventHandler(\n\t\tcmd.Log,\n\t\tcmd.Args.Path,\n\t\tcmd.Args.Watch,\n\t\topts,\n\t\tcmd.Args.GenerateSourceMapVisualisations,\n\t\tcmd.Args.KeepOrphanedFiles,\n\t\tcmd.Args.FileWriter,\n\t\tcmd.Args.Lazy,\n\t)\n\n\t// If we're processing a single file, don't bother setting up the channels/multithreaing.\n\tif cmd.Args.FileName != \"\" {\n\t\t_, err = fseh.HandleEvent(ctx, fsnotify.Event{\n\t\t\tName: cmd.Args.FileName,\n\t\t\tOp:   fsnotify.Create,\n\t\t})\n\t\treturn err\n\t}\n\n\t// Start timer.\n\tstart := time.Now()\n\n\t// For the initial filesystem walk and subsequent (optional) fsnotify events.\n\tevents := make(chan fsnotify.Event)\n\t// For errs from the watcher.\n\terrs := make(chan error)\n\n\t// Start process to push events into the events channel.\n\tgrp, ctx := errgroup.WithContext(ctx)\n\tgrp.Go(func() error {\n\t\tdefer close(events)\n\t\tcmd.walkAndWatch(ctx, events, errs)\n\t\treturn nil\n\t})\n\n\t// For triggering actions after generation has completed.\n\tpostGeneration := make(chan *GenerationEvent, 256)\n\n\t// Start process to handle events.\n\tgrp.Go(func() error {\n\t\tdefer close(postGeneration)\n\t\tcmd.handleEvents(ctx, events, errs, fseh, postGeneration)\n\t\treturn nil\n\t})\n\n\t// Start process to handle post-generation events.\n\tvar updates int\n\tgrp.Go(func() error {\n\t\tdefer close(errs)\n\t\tupdates, err = cmd.handlePostGenerationEvents(ctx, postGeneration)\n\t\treturn err\n\t})\n\n\t// Read errors.\n\tvar errorCount int\n\tfor err := range errs {\n\t\tif err == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif errors.Is(err, FatalError{}) {\n\t\t\tcmd.Log.Debug(\"Fatal error, exiting\")\n\t\t\treturn err\n\t\t}\n\t\tcmd.Log.Error(\"Error\", slog.Any(\"error\", err))\n\t\terrorCount++\n\t}\n\n\t// Wait for everything to complete.\n\tcmd.Log.Debug(\"Waiting for processes to complete\")\n\tif err = grp.Wait(); err != nil {\n\t\treturn err\n\t}\n\tif cmd.Args.Command != \"\" {\n\t\tcmd.Log.Debug(\"Killing command\", slog.String(\"command\", cmd.Args.Command))\n\t\tif err := run.KillAll(); err != nil {\n\t\t\tcmd.Log.Error(\"Error killing command\", slog.Any(\"error\", err))\n\t\t}\n\t}\n\n\t// Clean up temporary watch mode text files.\n\tif err := cmd.deleteWatchModeTextFiles(); err != nil {\n\t\tcmd.Log.Warn(\"Failed to delete watch mode text files\", slog.Any(\"error\", err))\n\t}\n\n\t// Check for errors after everything has completed.\n\tif errorCount > 0 {\n\t\treturn fmt.Errorf(\"generation completed with %d errors\", errorCount)\n\t}\n\n\tcmd.Log.Info(\"Complete\", slog.Int(\"updates\", updates), slog.Duration(\"duration\", time.Since(start)))\n\treturn nil\n}\n\nfunc (cmd Generate) groupUntilNoMessagesReceivedFor100ms(postGeneration chan *GenerationEvent) (grouped *GenerationEvent, updates int, ok bool, err error) {\n\ttimeout := time.NewTimer(time.Hour * 24 * 365)\nloop:\n\tfor {\n\t\tselect {\n\t\tcase ge := <-postGeneration:\n\t\t\tif ge == nil {\n\t\t\t\tcmd.Log.Debug(\"Post-generation event channel closed, exiting\")\n\t\t\t\treturn nil, 0, false, nil\n\t\t\t}\n\t\t\tif grouped == nil {\n\t\t\t\tgrouped = ge\n\t\t\t}\n\t\t\tgrouped.WatchedFileUpdated = grouped.WatchedFileUpdated || ge.WatchedFileUpdated\n\t\t\tgrouped.TemplFileTextUpdated = grouped.TemplFileTextUpdated || ge.TemplFileTextUpdated\n\t\t\tgrouped.TemplFileGoUpdated = grouped.TemplFileGoUpdated || ge.TemplFileGoUpdated\n\t\t\tif grouped.WatchedFileUpdated || grouped.TemplFileTextUpdated || grouped.TemplFileGoUpdated {\n\t\t\t\tupdates++\n\t\t\t}\n\t\t\t// Now we have received an event, wait for 100ms.\n\t\t\t// If no further messages are received in that time, the timeout will trigger.\n\t\t\ttimeout = time.NewTimer(time.Millisecond * 100)\n\t\tcase <-timeout.C:\n\t\t\t// If grouped is nil, or if no updates were made, reset the timer and continue waiting.\n\t\t\tif grouped == nil || (!grouped.WatchedFileUpdated && !grouped.TemplFileTextUpdated && !grouped.TemplFileGoUpdated) {\n\t\t\t\ttimeout = time.NewTimer(time.Hour * 24 * 365)\n\t\t\t\tcontinue loop\n\t\t\t}\n\t\t\t// We have a grouped event, and no events have been sent in the last 100ms, so we need to return.\n\t\t\treturn grouped, updates, true, nil\n\t\t}\n\t}\n}\n\nfunc (cmd Generate) handlePostGenerationEvents(ctx context.Context, postGeneration chan *GenerationEvent) (updates int, err error) {\n\tcmd.Log.Debug(\"Starting post-generation handler\")\n\tvar p *proxy.Handler\nloop:\n\tfor {\n\t\tgrouped, updated, ok, err := cmd.groupUntilNoMessagesReceivedFor100ms(postGeneration)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"error grouping post-generation events: %w\", err)\n\t\t}\n\t\tif !ok {\n\t\t\tbreak loop\n\t\t}\n\n\t\t// The Go application needs to be restarted if any watched non-templ watched files (i.e. non-templ Go files)\n\t\t// were updated, or if any Go code within a templ file was updated.\n\t\tneedsRestart := grouped.WatchedFileUpdated || grouped.TemplFileGoUpdated\n\t\t// If the text in a templ file, or any other changes have happened, reload the browser.\n\t\tneedsBrowserReload := grouped.TemplFileTextUpdated || grouped.TemplFileGoUpdated || grouped.WatchedFileUpdated\n\n\t\tcmd.Log.Info(\"Post-generation event received, processing...\", slog.Bool(\"needsRestart\", needsRestart), slog.Bool(\"needsBrowserReload\", needsBrowserReload))\n\t\tupdates += updated\n\n\t\tif cmd.Args.Command != \"\" && needsRestart {\n\t\t\tcmd.Log.Info(\"Executing command\", slog.String(\"command\", cmd.Args.Command))\n\t\t\tif cmd.Args.Watch {\n\t\t\t\tif err := os.Setenv(\"TEMPL_DEV_MODE\", \"true\"); err != nil {\n\t\t\t\t\tcmd.Log.Error(\"Error setting TEMPL_DEV_MODE environment variable\", slog.Any(\"error\", err))\n\t\t\t\t}\n\t\t\t\t// Check that the path is absolute.\n\t\t\t\t// It should have already been made absolute at the start of the Run method, but just in case, we need to make sure it's absolute before setting it as an environment variable.\n\t\t\t\tif !filepath.IsAbs(cmd.Args.Path) {\n\t\t\t\t\tcmd.Log.Error(\"Path is not absolute, this may cause issues with the command execution\", slog.String(\"path\", cmd.Args.Path))\n\t\t\t\t}\n\t\t\t\t// Evaluate symlinks to match the behavior in runtime/watchmode.go.\n\t\t\t\twatchRoot := cmd.Args.Path\n\t\t\t\tif resolved, err := filepath.EvalSymlinks(watchRoot); err == nil {\n\t\t\t\t\twatchRoot = resolved\n\t\t\t\t}\n\t\t\t\tif err := os.Setenv(\"TEMPL_DEV_MODE_WATCH_ROOT\", watchRoot); err != nil {\n\t\t\t\t\tcmd.Log.Error(\"Error setting TEMPL_DEV_MODE_WATCH_ROOT environment variable\", slog.Any(\"error\", err))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif _, err := run.Run(ctx, cmd.Args.Path, cmd.Args.Command); err != nil {\n\t\t\t\tcmd.Log.Error(\"Error executing command\", slog.Any(\"error\", err))\n\t\t\t}\n\t\t}\n\t\tif cmd.Args.Proxy != \"\" {\n\t\t\tif p == nil {\n\t\t\t\tcmd.Log.Debug(\"Starting proxy...\")\n\t\t\t\tp, err = cmd.startProxy()\n\t\t\t\tif err != nil {\n\t\t\t\t\tcmd.Log.Error(\"Failed to start proxy\", slog.Any(\"error\", err))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif needsBrowserReload {\n\t\t\t\tcmd.Log.Debug(\"Sending reload event\")\n\t\t\t\tp.SendSSE(\"message\", \"reload\")\n\t\t\t}\n\t\t}\n\t}\n\treturn updates, nil\n}\n\nfunc (cmd Generate) handleEvents(ctx context.Context, events chan fsnotify.Event, errs chan error, fseh *FSEventHandler, postGeneration chan *GenerationEvent) {\n\tvar eventsWG sync.WaitGroup\n\tsem := make(chan struct{}, cmd.Args.WorkerCount)\n\tcmd.Log.Debug(\"Starting event handler\")\n\tfor event := range events {\n\t\teventsWG.Add(1)\n\t\tsem <- struct{}{}\n\t\tgo func(event fsnotify.Event) {\n\t\t\tcmd.Log.Debug(\"Processing file\", slog.String(\"file\", event.Name))\n\t\t\tdefer eventsWG.Done()\n\t\t\tdefer func() { <-sem }()\n\t\t\tr, err := fseh.HandleEvent(ctx, event)\n\t\t\tif err != nil {\n\t\t\t\terrs <- err\n\t\t\t}\n\t\t\tif !r.WatchedFileUpdated && !r.TemplFileTextUpdated && !r.TemplFileGoUpdated {\n\t\t\t\tcmd.Log.Debug(\"File not updated\", slog.String(\"file\", event.Name))\n\t\t\t\treturn\n\t\t\t}\n\t\t\te := &GenerationEvent{\n\t\t\t\tEvent:                event,\n\t\t\t\tWatchedFileUpdated:   r.WatchedFileUpdated,\n\t\t\t\tTemplFileTextUpdated: r.TemplFileTextUpdated,\n\t\t\t\tTemplFileGoUpdated:   r.TemplFileGoUpdated,\n\t\t\t}\n\t\t\tcmd.Log.Debug(\"File updated\", slog.String(\"file\", event.Name))\n\t\t\tpostGeneration <- e\n\t\t}(event)\n\t}\n\t// Wait for all events to be processed before closing.\n\teventsWG.Wait()\n}\n\nfunc (cmd *Generate) walkAndWatch(ctx context.Context, events chan fsnotify.Event, errs chan error) {\n\tcmd.Log.Debug(\"Walking directory\", slog.String(\"path\", cmd.Args.Path), slog.Bool(\"devMode\", cmd.Args.Watch))\n\tif err := watcher.WalkFiles(ctx, cmd.Args.Path, cmd.Args.WatchPattern, cmd.Args.IgnorePattern, events); err != nil {\n\t\tcmd.Log.Error(\"WalkFiles failed, exiting\", slog.Any(\"error\", err))\n\t\terrs <- FatalError{Err: fmt.Errorf(\"failed to walk files: %w\", err)}\n\t\treturn\n\t}\n\tif !cmd.Args.Watch {\n\t\tcmd.Log.Debug(\"Dev mode not enabled, process can finish early\")\n\t\treturn\n\t}\n\tcmd.Log.Info(\"Watching files\")\n\trw, err := watcher.Recursive(ctx, cmd.Args.WatchPattern, cmd.Args.IgnorePattern, events, errs)\n\tif err != nil {\n\t\tcmd.Log.Error(\"Recursive watcher setup failed, exiting\", slog.Any(\"error\", err))\n\t\terrs <- FatalError{Err: fmt.Errorf(\"failed to setup recursive watcher: %w\", err)}\n\t\treturn\n\t}\n\tif err = rw.Add(cmd.Args.Path); err != nil {\n\t\tcmd.Log.Error(\"Failed to add path to watcher\", slog.Any(\"error\", err))\n\t\terrs <- FatalError{Err: fmt.Errorf(\"failed to add path to watcher: %w\", err)}\n\t\treturn\n\t}\n\tdefer func() {\n\t\tif err := rw.Close(); err != nil {\n\t\t\tcmd.Log.Error(\"Failed to close watcher\", slog.Any(\"error\", err))\n\t\t}\n\t}()\n\tcmd.Log.Debug(\"Waiting for context to be cancelled to stop watching files\")\n\t<-ctx.Done()\n}\n\nfunc (cmd *Generate) deleteWatchModeTextFiles() error {\n\treturn fs.WalkDir(os.DirFS(cmd.Args.Path), \".\", func(path string, info os.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tabsPath, err := filepath.Abs(filepath.Join(cmd.Args.Path, path))\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif info.IsDir() && skipdir.ShouldSkip(absPath) {\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\tif !strings.HasSuffix(absPath, \"_templ.go\") && !strings.HasSuffix(absPath, \".templ\") {\n\t\t\treturn nil\n\t\t}\n\t\twatchModeFileName := templruntime.GetDevModeTextFileName(absPath)\n\t\tif err := os.Remove(watchModeFileName); err != nil && !errors.Is(err, os.ErrNotExist) {\n\t\t\tcmd.Log.Warn(\"Failed to remove watch mode text file\", slog.Any(\"error\", err))\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc (cmd *Generate) createTLSTransport() *http.Transport {\n\tcertPEM, err := os.ReadFile(cmd.Args.ProxyTLSCrt)\n\tif err != nil {\n\t\tcmd.Log.Error(\"Failed to read TLS certificate file\", slog.Any(\"error\", err))\n\t\treturn nil\n\t}\n\tcertPool := x509.NewCertPool()\n\tif !certPool.AppendCertsFromPEM(certPEM) {\n\t\tcmd.Log.Error(\"Failed to append certificate to pool\")\n\t\treturn nil\n\t}\n\treturn &http.Transport{\n\t\tTLSClientConfig: &tls.Config{RootCAs: certPool},\n\t}\n}\n\nfunc (cmd *Generate) startProxy() (p *proxy.Handler, err error) {\n\tvar target *url.URL\n\ttarget, err = url.Parse(cmd.Args.Proxy)\n\tif err != nil {\n\t\treturn nil, FatalError{Err: fmt.Errorf(\"failed to parse proxy URL: %w\", err)}\n\t}\n\tscheme := \"http\"\n\tif cmd.Args.ProxyTLSCrt != \"\" && cmd.Args.ProxyTLSKey != \"\" {\n\t\tscheme = \"https\"\n\t}\n\tp = proxy.New(cmd.Log, scheme, cmd.Args.ProxyBind, cmd.Args.ProxyPort, target)\n\tgo func() {\n\t\tcmd.Log.Info(\"Proxying\", slog.String(\"from\", p.URL), slog.String(\"to\", p.Target.String()))\n\t\tserver := &http.Server{\n\t\t\tAddr:    fmt.Sprintf(\"%s:%d\", cmd.Args.ProxyBind, cmd.Args.ProxyPort),\n\t\t\tHandler: p,\n\t\t}\n\t\t// Configure TLS if certificates are provided.\n\t\tif cmd.Args.ProxyTLSCrt != \"\" && cmd.Args.ProxyTLSKey != \"\" {\n\t\t\tcert, err := tls.LoadX509KeyPair(cmd.Args.ProxyTLSCrt, cmd.Args.ProxyTLSKey)\n\t\t\tif err != nil {\n\t\t\t\tcmd.Log.Error(\"Failed to load TLS certificates\", slog.Any(\"error\", err))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tserver.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}\n\t\t\tif err = server.ListenAndServeTLS(cmd.Args.ProxyTLSCrt, cmd.Args.ProxyTLSKey); err != nil {\n\t\t\t\tcmd.Log.Error(\"Proxy failed\", slog.Any(\"error\", err))\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif err := server.ListenAndServe(); err != nil {\n\t\t\tcmd.Log.Error(\"Proxy failed\", slog.Any(\"error\", err))\n\t\t}\n\t}()\n\tif !cmd.Args.OpenBrowser {\n\t\tcmd.Log.Debug(\"Not opening browser\")\n\t\treturn p, nil\n\t}\n\tgo func() {\n\t\tcmd.Log.Debug(\"Waiting for proxy to be ready\", slog.String(\"url\", p.URL))\n\t\tbackoff := backoff.NewExponentialBackOff()\n\t\tbackoff.InitialInterval = time.Second\n\t\tvar client http.Client\n\t\tclient.Timeout = 1 * time.Second\n\t\t// Configure TLS with CA pool for self-signed certificates on localhost.\n\t\tif cmd.Args.ProxyTLSCrt != \"\" && cmd.Args.ProxyTLSKey != \"\" {\n\t\t\tclient.Transport = cmd.createTLSTransport()\n\t\t}\n\t\tfor {\n\t\t\tif resp, err := client.Get(p.URL); err == nil {\n\t\t\t\tif resp.StatusCode != http.StatusBadGateway {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\td := backoff.NextBackOff()\n\t\t\tcmd.Log.Debug(\"Proxy not ready, retrying\", slog.String(\"url\", p.URL), slog.Any(\"backoff\", d))\n\t\t\ttime.Sleep(d)\n\t\t}\n\t\tif err := browser.OpenURL(p.URL); err != nil {\n\t\t\tcmd.Log.Error(\"Failed to open browser\", slog.Any(\"error\", err))\n\t\t}\n\t}()\n\treturn p, nil\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/eventhandler.go",
    "content": "package generatecmd\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"go/format\"\n\t\"go/scanner\"\n\t\"go/token\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/cmd/templ/visualize\"\n\t\"github.com/a-h/templ/generator\"\n\t\"github.com/a-h/templ/internal/syncmap\"\n\t\"github.com/a-h/templ/internal/syncset\"\n\t\"github.com/a-h/templ/parser/v2\"\n\t\"github.com/a-h/templ/runtime\"\n\t\"github.com/fsnotify/fsnotify\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\ntype FileWriterFunc func(name string, contents []byte) error\n\nfunc FileWriter(fileName string, contents []byte) error {\n\treturn os.WriteFile(fileName, contents, 0o644)\n}\n\nfunc WriterFileWriter(w io.Writer) FileWriterFunc {\n\treturn func(_ string, contents []byte) error {\n\t\t_, err := w.Write(contents)\n\t\treturn err\n\t}\n}\n\nfunc NewFSEventHandler(\n\tlog *slog.Logger,\n\tdir string,\n\tdevMode bool,\n\tgenOpts []generator.GenerateOpt,\n\tgenSourceMapVis bool,\n\tkeepOrphanedFiles bool,\n\tfileWriter FileWriterFunc,\n\tlazy bool,\n) *FSEventHandler {\n\tif !path.IsAbs(dir) {\n\t\tdir, _ = filepath.Abs(dir)\n\t}\n\tfseh := &FSEventHandler{\n\t\tLog:                   log,\n\t\tdir:                   dir,\n\t\tfileNameToLastModTime: syncmap.New[string, time.Time](),\n\t\tfileNameToError:       syncset.New[string](),\n\t\tfileNameToOutput:      syncmap.New[string, generator.GeneratorOutput](),\n\t\tdevMode:               devMode,\n\t\thashes:                syncmap.New[string, [sha256.Size]byte](),\n\t\tgenOpts:               genOpts,\n\t\tgenSourceMapVis:       genSourceMapVis,\n\t\tkeepOrphanedFiles:     keepOrphanedFiles,\n\t\twriter:                fileWriter,\n\t\tlazy:                  lazy,\n\t}\n\treturn fseh\n}\n\ntype FSEventHandler struct {\n\tLog *slog.Logger\n\t// dir is the root directory being processed.\n\tdir                   string\n\tfileNameToLastModTime *syncmap.Map[string, time.Time]\n\tfileNameToError       *syncset.Set[string]\n\tfileNameToOutput      *syncmap.Map[string, generator.GeneratorOutput]\n\tdevMode               bool\n\thashes                *syncmap.Map[string, [sha256.Size]byte]\n\tgenOpts               []generator.GenerateOpt\n\tgenSourceMapVis       bool\n\tErrors                []error\n\tkeepOrphanedFiles     bool\n\twriter                FileWriterFunc\n\tlazy                  bool\n}\n\ntype GenerateResult struct {\n\t// WatchedFileUpdated indicates that a file matching the watch pattern was updated.\n\tWatchedFileUpdated bool\n\t// TemplFileTextUpdated indicates that text literals were updated.\n\tTemplFileTextUpdated bool\n\t// TemplFileGoUpdated indicates that Go expressions were updated.\n\tTemplFileGoUpdated bool\n}\n\nfunc (h *FSEventHandler) HandleEvent(ctx context.Context, event fsnotify.Event) (result GenerateResult, err error) {\n\t// Handle _templ.go files.\n\tif !event.Has(fsnotify.Remove) && strings.HasSuffix(event.Name, \"_templ.go\") {\n\t\t_, err = os.Stat(strings.TrimSuffix(event.Name, \"_templ.go\") + \".templ\")\n\t\tif !os.IsNotExist(err) {\n\t\t\treturn GenerateResult{}, err\n\t\t}\n\t\t// File is orphaned.\n\t\tif h.keepOrphanedFiles {\n\t\t\treturn GenerateResult{}, nil\n\t\t}\n\t\th.Log.Debug(\"Deleting orphaned Go file\", slog.String(\"file\", event.Name))\n\t\tif err = os.Remove(event.Name); err != nil {\n\t\t\th.Log.Warn(\"Failed to remove orphaned file\", slog.Any(\"error\", err))\n\t\t}\n\t\treturn GenerateResult{WatchedFileUpdated: false, TemplFileGoUpdated: true, TemplFileTextUpdated: false}, nil\n\t}\n\n\t// If the file hasn't been updated since the last time we processed it, ignore it.\n\tfileInfo, err := os.Stat(event.Name)\n\tif err != nil {\n\t\treturn GenerateResult{}, fmt.Errorf(\"failed to stat %q: %w\", event.Name, err)\n\t}\n\tmustBeInTheFuture := func(previous, updated time.Time) bool {\n\t\treturn updated.After(previous)\n\t}\n\tupdatedModTime := h.fileNameToLastModTime.CompareAndSwap(event.Name, mustBeInTheFuture, fileInfo.ModTime())\n\tif !updatedModTime {\n\t\th.Log.Debug(\"Skipping file because it wasn't updated\", slog.String(\"file\", event.Name))\n\t\treturn GenerateResult{}, nil\n\t}\n\n\t// Process anything that isn't a templ file.\n\tif !strings.HasSuffix(event.Name, \".templ\") {\n\t\tif h.devMode {\n\t\t\th.Log.Info(\"Watched file updated\", slog.String(\"file\", event.Name))\n\t\t}\n\t\tresult.WatchedFileUpdated = true\n\t\treturn result, nil\n\t}\n\n\t// Handle templ files.\n\n\t// If the go file is newer than the templ file, skip generation, because it's up-to-date.\n\tif h.lazy && goFileIsUpToDate(event.Name, fileInfo.ModTime()) {\n\t\th.Log.Debug(\"Skipping file because the Go file is up-to-date\", slog.String(\"file\", event.Name))\n\t\treturn GenerateResult{}, nil\n\t}\n\n\t// Start a processor.\n\tstart := time.Now()\n\tvar diag []parser.Diagnostic\n\tresult, diag, err = h.generate(ctx, event.Name)\n\tif err != nil {\n\t\th.fileNameToError.Set(event.Name)\n\t\treturn result, fmt.Errorf(\"failed to generate code for %q: %w\", event.Name, err)\n\t}\n\tif len(diag) > 0 {\n\t\tfor _, d := range diag {\n\t\t\th.Log.Warn(d.Message,\n\t\t\t\tslog.String(\"from\", fmt.Sprintf(\"%d:%d\", d.Range.From.Line, d.Range.From.Col)),\n\t\t\t\tslog.String(\"to\", fmt.Sprintf(\"%d:%d\", d.Range.To.Line, d.Range.To.Col)),\n\t\t\t)\n\t\t}\n\t\treturn result, nil\n\t}\n\tif errorCleared := h.fileNameToError.Delete(event.Name); errorCleared {\n\t\th.Log.Info(\"Error cleared\", slog.String(\"file\", event.Name), slog.Int(\"errors\", h.fileNameToError.Count()))\n\t}\n\th.Log.Debug(\"Generated code\", slog.String(\"file\", event.Name), slog.Duration(\"in\", time.Since(start)))\n\n\treturn result, nil\n}\n\nfunc goFileIsUpToDate(templFileName string, templFileLastMod time.Time) (upToDate bool) {\n\tgoFileName := strings.TrimSuffix(templFileName, \".templ\") + \"_templ.go\"\n\tgoFileInfo, err := os.Stat(goFileName)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn goFileInfo.ModTime().After(templFileLastMod)\n}\n\n// generate Go code for a single template.\n// If a basePath is provided, the filename included in error messages is relative to it.\nfunc (h *FSEventHandler) generate(ctx context.Context, fileName string) (result GenerateResult, diagnostics []parser.Diagnostic, err error) {\n\tt, err := parser.Parse(fileName)\n\tif err != nil {\n\t\treturn GenerateResult{}, nil, fmt.Errorf(\"%s parsing error: %w\", fileName, err)\n\t}\n\ttargetFileName := strings.TrimSuffix(fileName, \".templ\") + \"_templ.go\"\n\n\t// Only use relative filenames to the basepath for filenames in runtime error messages.\n\tabsFilePath, err := filepath.Abs(fileName)\n\tif err != nil {\n\t\treturn GenerateResult{}, nil, fmt.Errorf(\"failed to get absolute path for %q: %w\", fileName, err)\n\t}\n\trelFilePath, err := filepath.Rel(h.dir, absFilePath)\n\tif err != nil {\n\t\treturn GenerateResult{}, nil, fmt.Errorf(\"failed to get relative path for %q: %w\", fileName, err)\n\t}\n\t// Convert Windows file paths to Unix-style for consistency.\n\trelFilePath = filepath.ToSlash(relFilePath)\n\n\tvar b bytes.Buffer\n\tgeneratorOutput, err := generator.Generate(t, &b, append(h.genOpts, generator.WithFileName(relFilePath))...)\n\tif err != nil {\n\t\treturn GenerateResult{}, nil, fmt.Errorf(\"%s generation error: %w\", fileName, err)\n\t}\n\n\tformattedGoCode, err := format.Source(b.Bytes())\n\tif err != nil {\n\t\terr = remapErrorList(err, generatorOutput.SourceMap, fileName)\n\t\treturn GenerateResult{}, nil, fmt.Errorf(\"%s source formatting error %w\", fileName, err)\n\t}\n\n\t// Hash output, and write out the file if the goCodeHash has changed.\n\tgoCodeHash := sha256.Sum256(formattedGoCode)\n\tif h.hashes.CompareAndSwap(targetFileName, syncmap.UpdateIfChanged, goCodeHash) {\n\t\tif err = h.writer(targetFileName, formattedGoCode); err != nil {\n\t\t\treturn result, nil, fmt.Errorf(\"failed to write target file %q: %w\", targetFileName, err)\n\t\t}\n\t}\n\n\t// Add the txt file if it has changed.\n\tif h.devMode {\n\t\ttxtFileName := runtime.GetDevModeTextFileName(fileName)\n\t\th.Log.Debug(\"Writing development mode text file\", slog.String(\"file\", fileName), slog.String(\"output\", txtFileName))\n\t\tjoined := strings.Join(generatorOutput.Literals, \"\\n\")\n\t\ttxtHash := sha256.Sum256([]byte(joined))\n\t\tif h.hashes.CompareAndSwap(txtFileName, syncmap.UpdateIfChanged, txtHash) {\n\t\t\tif err = os.WriteFile(txtFileName, []byte(joined), 0o644); err != nil {\n\t\t\t\treturn result, nil, fmt.Errorf(\"failed to write string literal file %q: %w\", txtFileName, err)\n\t\t\t}\n\t\t}\n\t\t// Check whether the change would require a recompilation or text update to take effect.\n\t\tprevious, hasPrevious := h.fileNameToOutput.Get(fileName)\n\t\tif hasPrevious {\n\t\t\tresult.TemplFileTextUpdated = generator.HasTextChanged(previous, generatorOutput)\n\t\t\tresult.TemplFileGoUpdated = generator.HasGoChanged(previous, generatorOutput)\n\t\t}\n\t\th.fileNameToOutput.Set(fileName, generatorOutput)\n\t}\n\n\tparsedDiagnostics, err := parser.Diagnose(t)\n\tif err != nil {\n\t\treturn result, nil, fmt.Errorf(\"%s diagnostics error: %w\", fileName, err)\n\t}\n\n\tif h.genSourceMapVis {\n\t\terr = generateSourceMapVisualisation(ctx, fileName, targetFileName, generatorOutput.SourceMap)\n\t}\n\n\treturn result, parsedDiagnostics, err\n}\n\n// Takes an error from the formatter and attempts to convert the positions reported in the target file to their positions\n// in the source file.\nfunc remapErrorList(err error, sourceMap *parser.SourceMap, fileName string) error {\n\tlist, ok := err.(scanner.ErrorList)\n\tif !ok || len(list) == 0 {\n\t\treturn err\n\t}\n\tfor i, e := range list {\n\t\t// The positions in the source map are off by one line because of the package definition.\n\t\tsrcPos, ok := sourceMap.SourcePositionFromTarget(uint32(e.Pos.Line-1), uint32(e.Pos.Column))\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tlist[i].Pos = token.Position{\n\t\t\tFilename: fileName,\n\t\t\tOffset:   int(srcPos.Index),\n\t\t\tLine:     int(srcPos.Line) + 1,\n\t\t\tColumn:   int(srcPos.Col),\n\t\t}\n\t}\n\treturn list\n}\n\nfunc generateSourceMapVisualisation(ctx context.Context, templFileName, goFileName string, sourceMap *parser.SourceMap) error {\n\tif err := ctx.Err(); err != nil {\n\t\treturn err\n\t}\n\tvar templContents, goContents []byte\n\tvar grp errgroup.Group\n\tgrp.Go(func() (err error) {\n\t\ttemplContents, err = os.ReadFile(templFileName)\n\t\treturn err\n\t})\n\tgrp.Go(func() (err error) {\n\t\tgoContents, err = os.ReadFile(goFileName)\n\t\treturn err\n\t})\n\tif err := grp.Wait(); err != nil {\n\t\treturn err\n\t}\n\tcomponent := visualize.HTML(templFileName, string(templContents), string(goContents), sourceMap)\n\n\ttargetFileName := strings.TrimSuffix(templFileName, \".templ\") + \"_templ_sourcemap.html\"\n\tw, err := os.Create(targetFileName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"%s sourcemap visualisation error: %w\", templFileName, err)\n\t}\n\tb := bufio.NewWriter(w)\n\tif err = component.Render(ctx, b); err != nil {\n\t\t_ = w.Close()\n\t\treturn fmt.Errorf(\"%s sourcemap visualisation render error: %w\", templFileName, err)\n\t}\n\tif err = b.Flush(); err != nil {\n\t\t_ = w.Close()\n\t\treturn fmt.Errorf(\"%s sourcemap visualisation flush error: %w\", templFileName, err)\n\t}\n\tif err = w.Close(); err != nil {\n\t\treturn fmt.Errorf(\"%s sourcemap visualisation close error: %w\", templFileName, err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/fatalerror.go",
    "content": "package generatecmd\n\ntype FatalError struct {\n\tErr error\n}\n\nfunc (e FatalError) Error() string {\n\treturn e.Err.Error()\n}\n\nfunc (e FatalError) Unwrap() error {\n\treturn e.Err\n}\n\nfunc (e FatalError) Is(target error) bool {\n\t_, ok := target.(FatalError)\n\treturn ok\n}\n\nfunc (e FatalError) As(target any) bool {\n\t_, ok := target.(*FatalError)\n\treturn ok\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/main.go",
    "content": "package generatecmd\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"regexp\"\n\t\"runtime\"\n\n\t_ \"net/http/pprof\"\n\n\t\"github.com/a-h/templ/cmd/templ/sloghandler\"\n)\n\nconst generateUsageText = `usage: templ generate [<args>...]\n\nGenerates Go code from templ files.\n\nArgs:\n  -path <path>\n    Generates code for all files in path. (default .)\n  -f <file>\n    Optionally generates code for a single file, e.g. -f header.templ\n  -stdout\n    Prints to stdout instead of writing generated files to the filesystem.\n    Only applicable when -f is used.\n  -source-map-visualisations\n    Set to true to generate HTML files to visualise the templ code and its corresponding Go code.\n  -include-version\n    Set to false to skip inclusion of the templ version in the generated code. (default true)\n  -include-timestamp\n    Set to true to include the current time in the generated code.\n  -watch\n    Set to true to watch the path for changes and regenerate code.\n  -watch-pattern <regexp>\n    Set the regexp pattern of files that will be watched for changes. (default: '(.+\\.go$)|(.+\\.templ$)|(.+_templ\\.txt$)')\n  -ignore-pattern <regexp>\n    Set the regexp pattern of files to ignore when watching for changes. (default: '')\n  -cmd <cmd>\n    Set the command to run after generating code.\n  -proxy\n    Set the URL to proxy after generating code and executing the command.\n  -proxyport\n    The port the proxy will listen on. (default 7331)\n  -proxybind\n    The address the proxy will listen on. (default 127.0.0.1)\n  -notify-proxy\n    If present, the command will issue a reload event to the proxy 127.0.0.1:7331, or use proxyport and proxybind to specify a different address.\n  -w\n    Number of workers to use when generating code. (default runtime.NumCPUs)\n  -lazy\n    Only generate .go files if the source .templ file is newer.\n  -pprof\n    Port to run the pprof server on.\n  -keep-orphaned-files\n    Keeps orphaned generated templ files. (default false)\n  -v\n    Set log verbosity level to \"debug\". (default \"info\")\n  -log-level\n    Set log verbosity level. (default \"info\", options: \"debug\", \"info\", \"warn\", \"error\")\n  -help\n    Print help and exit.\n\nExamples:\n\n  Generate code for all files in the current directory and subdirectories:\n\n    templ generate\n\n  Generate code for a single file:\n\n    templ generate -f header.templ\n\n  Watch the current directory and subdirectories for changes and regenerate code:\n\n    templ generate -watch\n`\n\nconst defaultWatchPattern = `(.+\\.go$)|(.+\\.templ$)`\n\nfunc NewArguments(stdout, stderr io.Writer, args []string) (cmdArgs Arguments, log *slog.Logger, help bool, err error) {\n\tcmd := flag.NewFlagSet(\"generate\", flag.ContinueOnError)\n\tcmd.StringVar(&cmdArgs.FileName, \"f\", \"\", \"\")\n\tcmd.StringVar(&cmdArgs.Path, \"path\", \".\", \"\")\n\ttoStdoutFlag := cmd.Bool(\"stdout\", false, \"\")\n\tcmd.BoolVar(&cmdArgs.GenerateSourceMapVisualisations, \"source-map-visualisations\", false, \"\")\n\tcmd.BoolVar(&cmdArgs.IncludeVersion, \"include-version\", true, \"\")\n\tcmd.BoolVar(&cmdArgs.IncludeTimestamp, \"include-timestamp\", false, \"\")\n\tcmd.BoolVar(&cmdArgs.Watch, \"watch\", false, \"\")\n\twatchPatternFlag := cmd.String(\"watch-pattern\", defaultWatchPattern, \"\")\n\tignorePatternFlag := cmd.String(\"ignore-pattern\", \"\", \"\")\n\tcmd.BoolVar(&cmdArgs.OpenBrowser, \"open-browser\", true, \"\")\n\tcmd.StringVar(&cmdArgs.Command, \"cmd\", \"\", \"\")\n\tcmd.StringVar(&cmdArgs.Proxy, \"proxy\", \"\", \"\")\n\tcmd.IntVar(&cmdArgs.ProxyPort, \"proxyport\", 7331, \"\")\n\tcmd.StringVar(&cmdArgs.ProxyBind, \"proxybind\", \"127.0.0.1\", \"\")\n\tcmd.StringVar(&cmdArgs.ProxyTLSCrt, \"proxy-tls-crt\", \"\", \"\")\n\tcmd.StringVar(&cmdArgs.ProxyTLSKey, \"proxy-tls-key\", \"\", \"\")\n\tcmd.BoolVar(&cmdArgs.NotifyProxy, \"notify-proxy\", false, \"\")\n\tcmd.IntVar(&cmdArgs.WorkerCount, \"w\", runtime.NumCPU(), \"\")\n\tcmd.IntVar(&cmdArgs.PPROFPort, \"pprof\", 0, \"\")\n\tcmd.BoolVar(&cmdArgs.KeepOrphanedFiles, \"keep-orphaned-files\", false, \"\")\n\tcmd.BoolVar(&cmdArgs.Lazy, \"lazy\", false, \"\")\n\tverboseFlag := cmd.Bool(\"v\", false, \"\")\n\tlogLevelFlag := cmd.String(\"log-level\", \"info\", \"\")\n\thelpFlag := cmd.Bool(\"help\", false, \"\")\n\tif err = cmd.Parse(args); err != nil {\n\t\treturn Arguments{}, nil, false, fmt.Errorf(\"failed to parse arguments: %w\", err)\n\t}\n\n\tlog = sloghandler.NewLogger(*logLevelFlag, *verboseFlag, stderr)\n\n\tif cmdArgs.Watch && cmdArgs.FileName != \"\" {\n\t\treturn Arguments{}, log, *helpFlag, fmt.Errorf(\"cannot watch a single file, remove the -f or -watch flag\")\n\t}\n\tcmdArgs.WatchPattern, err = regexp.Compile(*watchPatternFlag)\n\tif err != nil {\n\t\treturn cmdArgs, log, *helpFlag, fmt.Errorf(\"invalid watch pattern %q: %w\", *watchPatternFlag, err)\n\t}\n\tif *ignorePatternFlag != \"\" {\n\t\tcmdArgs.IgnorePattern, err = regexp.Compile(*ignorePatternFlag)\n\t\tif err != nil {\n\t\t\treturn cmdArgs, log, *helpFlag, fmt.Errorf(\"invalid ignore pattern %q: %w\", *ignorePatternFlag, err)\n\t\t}\n\t}\n\n\t// Default to writing to files unless the stdout flag is set.\n\tcmdArgs.FileWriter = FileWriter\n\tif *toStdoutFlag {\n\t\tif cmdArgs.FileName == \"\" {\n\t\t\treturn Arguments{}, log, *helpFlag, fmt.Errorf(\"only a single file can be output to stdout, add the -f flag to specify the file to generate code for\")\n\t\t}\n\t\tcmdArgs.FileWriter = WriterFileWriter(stdout)\n\t}\n\n\t// Validate TLS certificate flags.\n\tif (cmdArgs.ProxyTLSCrt == \"\") != (cmdArgs.ProxyTLSKey == \"\") {\n\t\treturn Arguments{}, log, *helpFlag, fmt.Errorf(\"both -proxy-tls-crt and -proxy-tls-key must be provided together\")\n\t}\n\tif cmdArgs.ProxyTLSCrt != \"\" && cmdArgs.Proxy == \"\" {\n\t\treturn Arguments{}, log, *helpFlag, fmt.Errorf(\"-proxy-tls-crt and -proxy-tls-key can only be used with the -proxy flag\")\n\t}\n\n\treturn cmdArgs, log, *helpFlag, nil\n}\n\ntype Arguments struct {\n\tFileName                        string\n\tFileWriter                      FileWriterFunc\n\tPath                            string\n\tWatch                           bool\n\tWatchPattern                    *regexp.Regexp\n\tIgnorePattern                   *regexp.Regexp\n\tOpenBrowser                     bool\n\tCommand                         string\n\tProxyBind                       string\n\tProxyPort                       int\n\tProxy                           string\n\tProxyTLSCrt                     string\n\tProxyTLSKey                     string\n\tNotifyProxy                     bool\n\tWorkerCount                     int\n\tGenerateSourceMapVisualisations bool\n\tIncludeVersion                  bool\n\tIncludeTimestamp                bool\n\t// PPROFPort is the port to run the pprof server on.\n\tPPROFPort         int\n\tKeepOrphanedFiles bool\n\tLazy              bool\n}\n\ntype ArgumentError struct {\n\tMessage string\n}\n\nfunc (e *ArgumentError) Error() string {\n\treturn e.Message\n}\n\nfunc (a *ArgumentError) Code() int {\n\treturn 64 // EX_USAGE\n}\n\nfunc Run(ctx context.Context, stdout, stderr io.Writer, args []string) (err error) {\n\tcmdArgs, log, help, err := NewArguments(stdout, stderr, args)\n\tif err != nil {\n\t\t_, _ = fmt.Fprint(stderr, generateUsageText)\n\t\treturn &ArgumentError{\n\t\t\tMessage: err.Error(),\n\t\t}\n\t}\n\tif help {\n\t\t_, _ = fmt.Fprint(stdout, generateUsageText)\n\t\treturn nil\n\t}\n\tg, err := NewGenerate(log, cmdArgs)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn g.Run(ctx)\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/main_test.go",
    "content": "package generatecmd\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/cmd/templ/testproject\"\n\t\"github.com/a-h/templ/runtime\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\nfunc TestGenerate(t *testing.T) {\n\tt.Run(\"can print help\", func(t *testing.T) {\n\t\t// templ generate -help\n\t\tstdout := &bytes.Buffer{}\n\t\terr := Run(context.Background(), stdout, io.Discard, []string{\"-help\"})\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to run generate command: %v\", err)\n\t\t}\n\t\tif !strings.Contains(stdout.String(), \"usage: templ generate\") {\n\t\t\tt.Fatalf(\"expected help output, got: %s\", stdout.String())\n\t\t}\n\t})\n\tt.Run(\"can generate a file in place\", func(t *testing.T) {\n\t\t// templ generate -f templates.templ\n\t\tdir, err := testproject.Create(\"github.com/a-h/templ/cmd/templ/testproject\")\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to create test project: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := os.RemoveAll(dir); err != nil {\n\t\t\t\tt.Errorf(\"failed to remove test project directory: %v\", err)\n\t\t\t}\n\t\t}()\n\n\t\t// Delete the templates_templ.go file to ensure it is generated.\n\t\terr = os.Remove(path.Join(dir, \"templates_templ.go\"))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to remove templates_templ.go: %v\", err)\n\t\t}\n\n\t\t// Run the generate command.\n\t\terr = Run(context.Background(), io.Discard, io.Discard, []string{\"-f\", path.Join(dir, \"templates.templ\")})\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to run generate command: %v\", err)\n\t\t}\n\n\t\t// Check the templates_templ.go file was created.\n\t\t_, err = os.Stat(path.Join(dir, \"templates_templ.go\"))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"templates_templ.go was not created: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"can generate a file in watch mode\", func(t *testing.T) {\n\t\t// templ generate -f templates.templ\n\t\tdir, err := testproject.Create(\"github.com/a-h/templ/cmd/templ/testproject\")\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to create test project: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := os.RemoveAll(dir); err != nil {\n\t\t\t\tt.Errorf(\"failed to remove test project directory: %v\", err)\n\t\t\t}\n\t\t}()\n\n\t\t// Delete the templates_templ.go file to ensure it is generated.\n\t\terr = os.Remove(path.Join(dir, \"templates_templ.go\"))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to remove templates_templ.go: %v\", err)\n\t\t}\n\t\tctx, cancel := context.WithCancel(context.Background())\n\n\t\tvar eg errgroup.Group\n\t\teg.Go(func() error {\n\t\t\treturn Run(ctx, io.Discard, io.Discard, []string{\"-path\", dir, \"-watch\"})\n\t\t})\n\n\t\t// Check the templates_templ.go file was created, with backoff.\n\t\tdevModeTextFileName := runtime.GetDevModeTextFileName(path.Join(dir, \"templates_templ.go\"))\n\t\tfor i := range 5 {\n\t\t\ttime.Sleep(time.Second * time.Duration(i))\n\t\t\t_, err = os.Stat(path.Join(dir, \"templates_templ.go\"))\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t_, err = os.Stat(devModeTextFileName)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"template files were not created: %v\", err)\n\t\t}\n\n\t\tcancel()\n\t\tif err := eg.Wait(); err != nil {\n\t\t\tt.Errorf(\"generate command failed: %v\", err)\n\t\t}\n\n\t\t// Check the templates_templ.txt file was removed.\n\t\t_, err = os.Stat(path.Join(dir, devModeTextFileName))\n\t\tif err == nil {\n\t\t\tt.Error(\"templates_templ.txt was not removed\")\n\t\t}\n\t})\n}\n\nfunc TestDefaultWatchPattern(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\tmatches bool\n\t}{\n\t\t{\n\t\t\tname:    \"empty file names do not match\",\n\t\t\tinput:   \"\",\n\t\t\tmatches: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"*_templ.txt is no longer matched, Windows\",\n\t\t\tinput:   `C:\\Users\\adrian\\github.com\\a-h\\templ\\cmd\\templ\\testproject\\strings_templ.txt`,\n\t\t\tmatches: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"*_templ.txt is no longer matched, Unix\",\n\t\t\tinput:   \"/Users/adrian/github.com/a-h/templ/cmd/templ/testproject/strings_templ.txt\",\n\t\t\tmatches: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"*.templ files match, Windows\",\n\t\t\tinput:   `C:\\Users\\adrian\\github.com\\a-h\\templ\\cmd\\templ\\testproject\\templates.templ`,\n\t\t\tmatches: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"*.templ files match, Unix\",\n\t\t\tinput:   \"/Users/adrian/github.com/a-h/templ/cmd/templ/testproject/templates.templ\",\n\t\t\tmatches: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"*_templ.go files match, Windows\",\n\t\t\tinput:   `C:\\Users\\adrian\\github.com\\a-h\\templ\\cmd\\templ\\testproject\\templates_templ.go`,\n\t\t\tmatches: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"*_templ.go files match, Unix\",\n\t\t\tinput:   \"/Users/adrian/github.com/a-h/templ/cmd/templ/testproject/templates_templ.go\",\n\t\t\tmatches: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"*.go files match, Windows\",\n\t\t\tinput:   `C:\\Users\\adrian\\github.com\\a-h\\templ\\cmd\\templ\\testproject\\templates.go`,\n\t\t\tmatches: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"*.go files match, Unix\",\n\t\t\tinput:   \"/Users/adrian/github.com/a-h/templ/cmd/templ/testproject/templates.go\",\n\t\t\tmatches: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"*.css files do not match\",\n\t\t\tinput:   \"/Users/adrian/github.com/a-h/templ/cmd/templ/testproject/templates.css\",\n\t\t\tmatches: false,\n\t\t},\n\t}\n\twpRegexp, err := regexp.Compile(defaultWatchPattern)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to compile default watch pattern: %v\", err)\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tif wpRegexp.MatchString(test.input) != test.matches {\n\t\t\t\tt.Fatalf(\"expected match of %q to be %v\", test.input, test.matches)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestArgs(t *testing.T) {\n\tt.Run(\"Help is true if the help flag is set\", func(t *testing.T) {\n\t\t_, _, help, err := NewArguments(io.Discard, io.Discard, []string{\"-help\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif !help {\n\t\t\tt.Fatal(\"expected help to be true\")\n\t\t}\n\t})\n\tt.Run(\"Help is false if the help flag is not set\", func(t *testing.T) {\n\t\t_, _, help, err := NewArguments(io.Discard, io.Discard, []string{})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif help {\n\t\t\tt.Fatal(\"expected help to be false\")\n\t\t}\n\t})\n\tt.Run(\"The worker count is set to the number of CPUs if not specified\", func(t *testing.T) {\n\t\targs, _, _, err := NewArguments(io.Discard, io.Discard, []string{})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif args.WorkerCount == 0 {\n\t\t\tt.Fatal(\"expected worker count to be set to the number of CPUs\")\n\t\t}\n\t})\n\tt.Run(\"If toStdout is true, the file name must be specified\", func(t *testing.T) {\n\t\t_, _, _, err := NewArguments(io.Discard, io.Discard, []string{\"-stdout\"})\n\t\tif err == nil {\n\t\t\tt.Fatal(\"expected error when toStdout is true but no file name is specified\")\n\t\t}\n\t})\n\tt.Run(\"If toStdout is true, and the file name is specified, it writes to stdout\", func(t *testing.T) {\n\t\targs, _, _, err := NewArguments(io.Discard, io.Discard, []string{\"-stdout\", \"-f\", \"output.templ\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif args.FileName != \"output.templ\" {\n\t\t\tt.Fatalf(\"expected file name to be 'output.templ', got '%s'\", args.FileName)\n\t\t}\n\t\tif args.FileWriter == nil {\n\t\t\tt.Fatal(\"expected FileWriter to be set when toStdout is true\")\n\t\t}\n\t})\n\tt.Run(\"If the watchPattern is empty, it defaults to the default pattern\", func(t *testing.T) {\n\t\targs, _, _, err := NewArguments(io.Discard, io.Discard, []string{})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif args.WatchPattern.String() != defaultWatchPattern {\n\t\t\tt.Fatalf(\"expected watch pattern to be %q, got %q\", defaultWatchPattern, args.WatchPattern.String())\n\t\t}\n\t})\n\tt.Run(\"If the watchPattern is set, it is checked for validity\", func(t *testing.T) {\n\t\t_, _, _, err := NewArguments(io.Discard, io.Discard, []string{\"-watch-pattern\", \"invalid[pattern\"})\n\t\tif err == nil {\n\t\t\tt.Fatal(\"expected error when watch pattern is invalid\")\n\t\t}\n\t})\n\tt.Run(\"If the watch flag is set, watch is set to true\", func(t *testing.T) {\n\t\targs, _, _, err := NewArguments(io.Discard, io.Discard, []string{\"-watch\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif !args.Watch {\n\t\t\tt.Fatal(\"expected watch to be true when the watch flag is set\")\n\t\t}\n\t})\n\tt.Run(\"If the watch flag is not set, watch is false\", func(t *testing.T) {\n\t\targs, _, _, err := NewArguments(io.Discard, io.Discard, []string{})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif args.Watch {\n\t\t\tt.Fatal(\"expected watch to be false when the watch flag is not set\")\n\t\t}\n\t})\n\tt.Run(\"The cmd flag can be set to specify a command to run after generating\", func(t *testing.T) {\n\t\targs, _, _, err := NewArguments(io.Discard, io.Discard, []string{\"-cmd\", \"echo hello\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif args.Command != \"echo hello\" {\n\t\t\tt.Fatalf(\"expected command to be 'echo hello', got '%s'\", args.Command)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/modcheck/modcheck.go",
    "content": "package modcheck\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/a-h/templ\"\n\t\"golang.org/x/mod/modfile\"\n\t\"golang.org/x/mod/semver\"\n)\n\n// WalkUp the directory tree, starting at dir, until we find a directory containing\n// a go.mod file.\nfunc WalkUp(dir string) (string, error) {\n\tdir, err := filepath.Abs(dir)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get absolute path: %w\", err)\n\t}\n\n\tvar modFile string\n\tfor {\n\t\tmodFile = filepath.Join(dir, \"go.mod\")\n\t\t_, err := os.Stat(modFile)\n\t\tif err != nil && !os.IsNotExist(err) {\n\t\t\treturn \"\", fmt.Errorf(\"failed to stat go.mod file: %w\", err)\n\t\t}\n\t\tif os.IsNotExist(err) {\n\t\t\t// Move up.\n\t\t\tprev := dir\n\t\t\tdir = filepath.Dir(dir)\n\t\t\tif dir == prev {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tbreak\n\t}\n\n\t// No file found.\n\tif modFile == \"\" {\n\t\treturn dir, fmt.Errorf(\"could not find go.mod file\")\n\t}\n\treturn dir, nil\n}\n\nfunc Check(dir string) error {\n\tdir, err := WalkUp(dir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Found a go.mod file.\n\t// Read it and find the templ version.\n\tmodFile := filepath.Join(dir, \"go.mod\")\n\tm, err := os.ReadFile(modFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read go.mod file: %w\", err)\n\t}\n\n\tmf, err := modfile.Parse(modFile, m, nil)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse go.mod file: %w\", err)\n\t}\n\tif mf.Module.Mod.Path == \"github.com/a-h/templ\" {\n\t\t// The go.mod file is for templ itself.\n\t\treturn nil\n\t}\n\tfor _, r := range mf.Require {\n\t\tif r.Mod.Path == \"github.com/a-h/templ\" {\n\t\t\tcmp := semver.Compare(r.Mod.Version, templ.Version())\n\t\t\tif cmp < 0 {\n\t\t\t\treturn fmt.Errorf(\"generator %v is newer than templ version %v found in go.mod file, consider running `go get -u github.com/a-h/templ` to upgrade\", templ.Version(), r.Mod.Version)\n\t\t\t}\n\t\t\tif cmp > 0 {\n\t\t\t\treturn fmt.Errorf(\"generator %v is older than templ version %v found in go.mod file, consider upgrading templ CLI\", templ.Version(), r.Mod.Version)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn fmt.Errorf(\"templ not found in go.mod file, run `go get github.com/a-h/templ` to install it\")\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/modcheck/modcheck_test.go",
    "content": "package modcheck\n\nimport (\n\t\"testing\"\n\n\t\"golang.org/x/mod/modfile\"\n)\n\nfunc TestPatchGoVersion(t *testing.T) {\n\ttests := []struct {\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tinput:    \"go 1.20\",\n\t\t\texpected: \"1.20\",\n\t\t},\n\t\t{\n\t\t\tinput:    \"go 1.20.123\",\n\t\t\texpected: \"1.20.123\",\n\t\t},\n\t\t{\n\t\t\tinput:    \"go 1.20.1\",\n\t\t\texpected: \"1.20.1\",\n\t\t},\n\t\t{\n\t\t\tinput:    \"go 1.20rc1\",\n\t\t\texpected: \"1.20rc1\",\n\t\t},\n\t\t{\n\t\t\tinput:    \"go 1.15\",\n\t\t\texpected: \"1.15\",\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.input, func(t *testing.T) {\n\t\t\tinput := \"module github.com/a-h/templ\\n\\n\" + string(test.input) + \"\\n\" + \"toolchain go1.27.9\\n\"\n\t\t\tmf, err := modfile.Parse(\"go.mod\", []byte(input), nil)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to parse go.mod: %v\", err)\n\t\t\t}\n\t\t\tif test.expected != mf.Go.Version {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", test.expected, mf.Go.Version)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/proxy/proxy.go",
    "content": "package proxy\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\tstdlog \"log\"\n\t\"log/slog\"\n\t\"math\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/url\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/sse\"\n\t\"github.com/a-h/templ/internal/htmlfind\"\n\t\"github.com/andybalholm/brotli\"\n\t\"golang.org/x/net/html\"\n\n\t_ \"embed\"\n)\n\n//go:embed script.js\nvar script string\n\ntype Handler struct {\n\tlog    *slog.Logger\n\tURL    string\n\tTarget *url.URL\n\tp      *httputil.ReverseProxy\n\tsse    *sse.Handler\n}\n\nfunc reloadScript(nonce string) *html.Node {\n\tscript := &html.Node{\n\t\tType: html.ElementNode,\n\t\tData: \"script\",\n\t\tAttr: []html.Attribute{\n\t\t\t{Key: \"src\", Val: \"/_templ/reload/script.js\"},\n\t\t},\n\t}\n\tif nonce != \"\" {\n\t\tscript.Attr = append(script.Attr, html.Attribute{Key: \"nonce\", Val: nonce})\n\t}\n\treturn script\n}\n\nvar ErrBodyNotFound = fmt.Errorf(\"body not found\")\n\nfunc insertScriptTagIntoBody(nonce, body string) (updated string, err error) {\n\tn, err := html.Parse(strings.NewReader(body))\n\tif err != nil {\n\t\treturn body, err\n\t}\n\tbodyNodes := htmlfind.All(n, htmlfind.Element(\"body\"))\n\tif len(bodyNodes) == 0 {\n\t\treturn body, ErrBodyNotFound\n\t}\n\tbodyNodes[0].AppendChild(reloadScript(nonce))\n\tbuf := new(bytes.Buffer)\n\tif err = html.Render(buf, n); err != nil {\n\t\treturn body, err\n\t}\n\treturn buf.String(), nil\n}\n\nfunc isStreaming(r *http.Response, log *slog.Logger) bool {\n\tif strings.Contains(strings.ToLower(r.Header.Get(\"Transfer-Encoding\")), \"chunked\") {\n\t\tlog.DebugContext(r.Request.Context(), \"Response is streaming because transfer encoding is chunked\")\n\t\treturn true\n\t}\n\t// Some servers omit both TE and Content-Length, in Go that's -1.\n\tif r.Header.Get(\"Content-Length\") == \"\" && r.ContentLength == -1 {\n\t\tlog.DebugContext(r.Request.Context(), \"Response is streaming because content length is unspecified\")\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc streamInsertAfterBodyOpen(nonce string, r io.Reader, w io.Writer) error {\n\tz := html.NewTokenizer(r)\n\tinserted := false\n\tfor {\n\t\ttt := z.Next()\n\t\tswitch tt {\n\t\tcase html.ErrorToken:\n\t\t\tif z.Err() == io.EOF {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn z.Err()\n\t\tcase html.StartTagToken:\n\t\t\tt := z.Token()\n\t\t\t_, err := w.Write([]byte(t.String()))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif t.Data == \"body\" && !inserted {\n\t\t\t\tinserted = true\n\t\t\t\tscriptNode := reloadScript(nonce)\n\t\t\t\tvar buf bytes.Buffer\n\t\t\t\tif err := html.Render(&buf, scriptNode); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\t_, err = w.Write(buf.Bytes())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\t_, err := w.Write(z.Raw())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n}\n\ntype passthroughWriteCloser struct {\n\tio.Writer\n}\n\nfunc (pwc passthroughWriteCloser) Close() error {\n\treturn nil\n}\n\nconst unsupportedContentEncoding = \"Unsupported content encoding, hot reload script not inserted.\"\n\nfunc (h *Handler) modifyResponse(r *http.Response) error {\n\tlog := h.log.With(slog.String(\"url\", r.Request.URL.String()))\n\tif r.Header.Get(\"templ-skip-modify\") == \"true\" {\n\t\tlog.Debug(\"Skipping response modification because templ-skip-modify header is set\")\n\t\treturn nil\n\t}\n\tif contentType := r.Header.Get(\"Content-Type\"); !strings.HasPrefix(contentType, \"text/html\") {\n\t\tlog.Debug(\"Skipping response modification because content type is not text/html\", slog.String(\"content-type\", contentType))\n\t\treturn nil\n\t}\n\n\t// Set up readers and writers.\n\tnewReader := func(in io.Reader) (out io.Reader, err error) {\n\t\treturn in, nil\n\t}\n\tnewWriter := func(out io.Writer) io.WriteCloser {\n\t\treturn passthroughWriteCloser{out}\n\t}\n\tswitch r.Header.Get(\"Content-Encoding\") {\n\tcase \"gzip\":\n\t\tnewReader = func(in io.Reader) (out io.Reader, err error) {\n\t\t\treturn gzip.NewReader(in)\n\t\t}\n\t\tnewWriter = func(out io.Writer) io.WriteCloser {\n\t\t\treturn gzip.NewWriter(out)\n\t\t}\n\tcase \"br\":\n\t\tnewReader = func(in io.Reader) (out io.Reader, err error) {\n\t\t\treturn brotli.NewReader(in), nil\n\t\t}\n\t\tnewWriter = func(out io.Writer) io.WriteCloser {\n\t\t\treturn brotli.NewWriter(out)\n\t\t}\n\tcase \"\":\n\t\tlog.Debug(\"No content encoding header found\")\n\tdefault:\n\t\tlog.Warn(unsupportedContentEncoding, slog.String(\"encoding\", r.Header.Get(\"Content-Encoding\")))\n\t}\n\n\tcsp := r.Header.Get(\"Content-Security-Policy\")\n\tnonce := parseNonce(csp)\n\n\tif isStreaming(r, log) {\n\t\t// Create a pipe and replace the body with the read end of the pipe.\n\t\tpr, pw := io.Pipe()\n\t\toriginalBody := r.Body\n\t\tr.Body = pr\n\n\t\t// Start a goroutine to read from the original body, modify it, and write to the pipe.\n\t\tgo func() {\n\t\t\tdefer func() {\n\t\t\t\t_ = originalBody.Close()\n\t\t\t}()\n\t\t\tencr, err := newReader(originalBody)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debug(\"Failed to read streaming response\", slog.Any(\"error\", err))\n\t\t\t\t_ = pw.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tenc := newWriter(pw)\n\t\t\tdefer func() {\n\t\t\t\t_ = enc.Close()\n\t\t\t}()\n\n\t\t\tif err := streamInsertAfterBodyOpen(nonce, encr, enc); err != nil {\n\t\t\t\tlog.Debug(\"Failed to modify streaming response\", slog.Any(\"error\", err))\n\t\t\t\t_ = pw.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\t_ = pw.Close()\n\t\t}()\n\n\t\treturn nil\n\t}\n\n\t// Read the encoded body.\n\tencr, err := newReader(r.Body)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\t_ = r.Body.Close()\n\t}()\n\tbody, err := io.ReadAll(encr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Update it.\n\tupdated, err := insertScriptTagIntoBody(nonce, string(body))\n\tif err != nil {\n\t\tlog.Warn(\"Unable to insert reload script\", slog.Any(\"error\", err))\n\t\tupdated = string(body)\n\t}\n\tif len(updated) == len(body) {\n\t\tlog.Debug(\"Reload script not inserted\")\n\t} else {\n\t\tlog.Debug(\"Reload script inserted\")\n\t}\n\n\t// Encode the response.\n\tvar buf bytes.Buffer\n\tencw := newWriter(&buf)\n\t_, err = encw.Write([]byte(updated))\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = encw.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Update the response.\n\tr.Body = io.NopCloser(&buf)\n\tr.ContentLength = int64(buf.Len())\n\tr.Header.Set(\"Content-Length\", strconv.Itoa(buf.Len()))\n\treturn nil\n}\n\nfunc parseNonce(csp string) (nonce string) {\nouter:\n\tfor _, rawDirective := range strings.Split(csp, \";\") {\n\t\tparts := strings.Fields(rawDirective)\n\t\tif len(parts) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\tif parts[0] != \"script-src\" {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, source := range parts[1:] {\n\t\t\tsource = strings.TrimPrefix(source, \"'\")\n\t\t\tsource = strings.TrimSuffix(source, \"'\")\n\t\t\tif strings.HasPrefix(source, \"nonce-\") {\n\t\t\t\tnonce = source[6:]\n\t\t\t\tbreak outer\n\t\t\t}\n\t\t}\n\t}\n\treturn nonce\n}\n\nfunc New(log *slog.Logger, scheme string, bind string, port int, target *url.URL) (h *Handler) {\n\tp := httputil.NewSingleHostReverseProxy(target)\n\tp.ErrorLog = stdlog.New(os.Stderr, \"Proxy to target error: \", 0)\n\tp.Transport = &roundTripper{\n\t\tmaxRetries:      20,\n\t\tinitialDelay:    100 * time.Millisecond,\n\t\tbackoffExponent: 1.5,\n\t}\n\th = &Handler{\n\t\tlog:    log,\n\t\tURL:    fmt.Sprintf(\"%s://%s:%d\", scheme, bind, port),\n\t\tTarget: target,\n\t\tp:      p,\n\t\tsse:    sse.New(),\n\t}\n\tp.ModifyResponse = h.modifyResponse\n\treturn h\n}\n\nfunc (p *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif r.URL.Path == \"/_templ/reload/script.js\" {\n\t\t// Provides a script that reloads the page.\n\t\tw.Header().Add(\"Content-Type\", \"text/javascript\")\n\t\t_, err := io.WriteString(w, script)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"failed to write script: %v\\n\", err)\n\t\t}\n\t\treturn\n\t}\n\tif r.URL.Path == \"/_templ/reload/events\" {\n\t\tswitch r.Method {\n\t\tcase http.MethodGet:\n\t\t\t// Provides a list of messages including a reload message.\n\t\t\tp.sse.ServeHTTP(w, r)\n\t\t\treturn\n\t\tcase http.MethodPost:\n\t\t\t// Send a reload message to all connected clients.\n\t\t\tp.sse.Send(\"message\", \"reload\")\n\t\t\treturn\n\t\t}\n\t\thttp.Error(w, \"only GET or POST method allowed\", http.StatusMethodNotAllowed)\n\t\treturn\n\t}\n\tp.p.ServeHTTP(w, r)\n}\n\nfunc (p *Handler) SendSSE(eventType string, data string) {\n\tp.sse.Send(eventType, data)\n}\n\ntype roundTripper struct {\n\tmaxRetries      int\n\tinitialDelay    time.Duration\n\tbackoffExponent float64\n}\n\nfunc (rt *roundTripper) setShouldSkipResponseModificationHeader(r *http.Request, resp *http.Response) {\n\t// Instruct the modifyResponse function to skip modifying the response if the\n\t// HTTP request has come from htmx or Datastar.\n\tif r.Header.Get(\"HX-Request\") != \"true\" && r.Header.Get(\"Datastar-Request\") != \"true\" {\n\t\treturn\n\t}\n\tresp.Header.Set(\"templ-skip-modify\", \"true\")\n}\n\nfunc (rt *roundTripper) RoundTrip(r *http.Request) (*http.Response, error) {\n\t// Read and buffer the body.\n\tvar bodyBytes []byte\n\tif r.Body != nil && r.Body != http.NoBody {\n\t\tvar err error\n\t\tbodyBytes, err = io.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err = r.Body.Close(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to close request body: %w\", err)\n\t\t}\n\t}\n\n\t// Retry logic.\n\tvar resp *http.Response\n\tvar err error\n\tfor retries := range rt.maxRetries {\n\t\t// Clone the request and set the body.\n\t\treq := r.Clone(r.Context())\n\t\tif bodyBytes != nil {\n\t\t\treq.Body = io.NopCloser(bytes.NewReader(bodyBytes))\n\t\t}\n\n\t\t// Execute the request.\n\t\tresp, err = http.DefaultTransport.RoundTrip(req)\n\t\tif err != nil || resp.StatusCode == http.StatusBadGateway {\n\t\t\ttime.Sleep(rt.initialDelay * time.Duration(math.Pow(rt.backoffExponent, float64(retries))))\n\t\t\tcontinue\n\t\t}\n\n\t\trt.setShouldSkipResponseModificationHeader(r, resp)\n\n\t\treturn resp, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"max retries reached: %q\", r.URL.String())\n}\n\nfunc NotifyProxy(host string, port int) error {\n\turlStr := fmt.Sprintf(\"http://%s:%d/_templ/reload/events\", host, port)\n\treq, err := http.NewRequest(http.MethodPost, urlStr, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = http.DefaultClient.Do(req)\n\treturn err\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/proxy/proxy_test.go",
    "content": "package proxy\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/andybalholm/brotli\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/net/html\"\n)\n\nfunc TestRoundTripper(t *testing.T) {\n\ttests := []struct {\n\t\tname         string\n\t\theaders      map[string]string\n\t\texpectedSkip string\n\t}{\n\t\t{\n\t\t\tname:         \"htmx requests skip modification\",\n\t\t\theaders:      map[string]string{\"HX-Request\": \"true\"},\n\t\t\texpectedSkip: \"true\",\n\t\t},\n\t\t{\n\t\t\tname:         \"Datastar requests skip modification\",\n\t\t\theaders:      map[string]string{\"Datastar-Request\": \"true\"},\n\t\t\texpectedSkip: \"true\",\n\t\t},\n\t\t{\n\t\t\tname:         \"Non-htmx and Datastar requests do not skip modification\",\n\t\t\theaders:      map[string]string{},\n\t\t\texpectedSkip: \"\",\n\t\t},\n\t}\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trt := &roundTripper{}\n\t\t\treq := httptest.NewRequest(\"GET\", \"http://example.com\", nil)\n\t\t\tfor k, v := range tc.headers {\n\t\t\t\treq.Header.Set(k, v)\n\t\t\t}\n\t\t\tresp := &http.Response{Header: make(http.Header)}\n\t\t\trt.setShouldSkipResponseModificationHeader(req, resp)\n\t\t\tif resp.Header.Get(\"templ-skip-modify\") != tc.expectedSkip {\n\t\t\t\tt.Errorf(\"expected templ-skip-modify header to be %q, got %q\", tc.expectedSkip, resp.Header.Get(\"templ-skip-modify\"))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc getScriptTag(t *testing.T, nonce string) string {\n\tscript := reloadScript(nonce)\n\tvar buf bytes.Buffer\n\terr := html.Render(&buf, script)\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error rendering script tag: %v\", err)\n\t}\n\treturn buf.String()\n}\n\nfunc TestProxy(t *testing.T) {\n\tt.Run(\"plain: non-html content is not modified\", func(t *testing.T) {\n\t\t// Arrange\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(strings.NewReader(`{\"key\": \"value\"}`)),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"application/json\")\n\t\tr.Header.Set(\"Content-Length\", \"16\")\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\terr := h.modifyResponse(r)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != \"16\" {\n\t\t\tt.Errorf(\"expected content length to be 16, got %v\", r.Header.Get(\"Content-Length\"))\n\t\t}\n\t\tactualBody, err := io.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(`{\"key\": \"value\"}`, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"plain: if the response contains templ-skip-modify header, it is not modified\", func(t *testing.T) {\n\t\t// Arrange\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(strings.NewReader(`Hello`)),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html\")\n\t\tr.Header.Set(\"Content-Length\", \"5\")\n\t\tr.Header.Set(\"templ-skip-modify\", \"true\")\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\terr := h.modifyResponse(r)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != \"5\" {\n\t\t\tt.Errorf(\"expected content length to be 5, got %v\", r.Header.Get(\"Content-Length\"))\n\t\t}\n\t\tactualBody, err := io.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(`Hello`, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"plain: body tags get the script inserted\", func(t *testing.T) {\n\t\t// Arrange\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(strings.NewReader(`<html><body></body></html>`)),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html, charset=utf-8\")\n\t\tr.Header.Set(\"Content-Length\", \"26\")\n\n\t\texpectedString, err := insertScriptTagIntoBody(\"\", `<html><body></body></html>`)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error inserting script: %v\", err)\n\t\t}\n\t\tif !strings.Contains(expectedString, getScriptTag(t, \"\")) {\n\t\t\tt.Fatalf(\"expected the script tag to be inserted, but it wasn't: %q\", expectedString)\n\t\t}\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\tif err = h.modifyResponse(r); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != fmt.Sprintf(\"%d\", len(expectedString)) {\n\t\t\tt.Errorf(\"expected content length to be %d, got %v\", len(expectedString), r.Header.Get(\"Content-Length\"))\n\t\t}\n\t\tactualBody, err := io.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(expectedString, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"plain: body tags get the script inserted with nonce\", func(t *testing.T) {\n\t\t// Arrange\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(strings.NewReader(`<html><body></body></html>`)),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html, charset=utf-8\")\n\t\tr.Header.Set(\"Content-Length\", \"26\")\n\t\tconst nonce = \"this-is-the-nonce\"\n\t\tr.Header.Set(\"Content-Security-Policy\", fmt.Sprintf(\"script-src 'nonce-%s'\", nonce))\n\n\t\texpectedString, err := insertScriptTagIntoBody(nonce, `<html><body></body></html>`)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error inserting script: %v\", err)\n\t\t}\n\t\tif !strings.Contains(expectedString, getScriptTag(t, nonce)) {\n\t\t\tt.Fatalf(\"expected the script tag to be inserted, but it wasn't: %q\", expectedString)\n\t\t}\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\tif err = h.modifyResponse(r); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != fmt.Sprintf(\"%d\", len(expectedString)) {\n\t\t\tt.Errorf(\"expected content length to be %d, got %v\", len(expectedString), r.Header.Get(\"Content-Length\"))\n\t\t}\n\t\tactualBody, err := io.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(expectedString, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"plain: body tags get the script inserted ignoring js with body tags\", func(t *testing.T) {\n\t\t// Arrange\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(strings.NewReader(`<html><body><script>console.log(\"<body></body>\")</script></body></html>`)),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html, charset=utf-8\")\n\t\tr.Header.Set(\"Content-Length\", \"26\")\n\n\t\texpectedString, err := insertScriptTagIntoBody(\"\", `<html><body><script>console.log(\"<body></body>\")</script></body></html>`)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error inserting script: %v\", err)\n\t\t}\n\t\tif !strings.Contains(expectedString, getScriptTag(t, \"\")) {\n\t\t\tt.Fatalf(\"expected the script tag to be inserted, but it wasn't: %q\", expectedString)\n\t\t}\n\t\tif !strings.Contains(expectedString, `console.log(\"<body></body>\")`) {\n\t\t\tt.Fatalf(\"expected the script tag to be inserted, but mangled the html: %q\", expectedString)\n\t\t}\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\tif err = h.modifyResponse(r); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != fmt.Sprintf(\"%d\", len(expectedString)) {\n\t\t\tt.Errorf(\"expected content length to be %d, got %v\", len(expectedString), r.Header.Get(\"Content-Length\"))\n\t\t}\n\t\tactualBody, err := io.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(expectedString, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"gzip: non-html content is not modified\", func(t *testing.T) {\n\t\t// Arrange\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(strings.NewReader(`{\"key\": \"value\"}`)),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"application/json\")\n\t\t// It's not actually gzipped here, but it doesn't matter, it shouldn't get that far.\n\t\tr.Header.Set(\"Content-Encoding\", \"gzip\")\n\t\t// Similarly, this is not the actual length of the gzipped content.\n\t\tr.Header.Set(\"Content-Length\", \"16\")\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\terr := h.modifyResponse(r)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != \"16\" {\n\t\t\tt.Errorf(\"expected content length to be 16, got %v\", r.Header.Get(\"Content-Length\"))\n\t\t}\n\t\tactualBody, err := io.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(`{\"key\": \"value\"}`, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"gzip: body tags get the script inserted\", func(t *testing.T) {\n\t\t// Arrange\n\t\tbody := `<html><body></body></html>`\n\t\tvar buf bytes.Buffer\n\t\tgzw := gzip.NewWriter(&buf)\n\t\t_, err := gzw.Write([]byte(body))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error writing gzip: %v\", err)\n\t\t}\n\t\tif err = gzw.Close(); err != nil {\n\t\t\tt.Fatalf(\"unexpected error closing gzip writer: %v\", err)\n\t\t}\n\n\t\texpectedString, err := insertScriptTagIntoBody(\"\", body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error inserting script: %v\", err)\n\t\t}\n\n\t\tvar expectedBytes bytes.Buffer\n\t\tgzw = gzip.NewWriter(&expectedBytes)\n\t\t_, err = gzw.Write([]byte(expectedString))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error writing gzip: %v\", err)\n\t\t}\n\t\tif err = gzw.Close(); err != nil {\n\t\t\tt.Fatalf(\"unexpected error closing gzip writer: %v\", err)\n\t\t}\n\t\texpectedLength := len(expectedBytes.Bytes())\n\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(&buf),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html, charset=utf-8\")\n\t\tr.Header.Set(\"Content-Encoding\", \"gzip\")\n\t\tr.Header.Set(\"Content-Length\", fmt.Sprintf(\"%d\", expectedLength))\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\terr = h.modifyResponse(r)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != fmt.Sprintf(\"%d\", expectedLength) {\n\t\t\tt.Errorf(\"expected content length to be %d, got %v\", expectedLength, r.Header.Get(\"Content-Length\"))\n\t\t}\n\n\t\tgr, err := gzip.NewReader(r.Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tactualBody, err := io.ReadAll(gr)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(expectedString, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"brotli: body tags get the script inserted\", func(t *testing.T) {\n\t\t// Arrange\n\t\tbody := `<html><body></body></html>`\n\t\tvar buf bytes.Buffer\n\t\tbrw := brotli.NewWriter(&buf)\n\t\t_, err := brw.Write([]byte(body))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error writing gzip: %v\", err)\n\t\t}\n\t\tif err = brw.Close(); err != nil {\n\t\t\tt.Fatalf(\"unexpected error closing brotli writer: %v\", err)\n\t\t}\n\n\t\texpectedString, err := insertScriptTagIntoBody(\"\", body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error inserting script: %v\", err)\n\t\t}\n\n\t\tvar expectedBytes bytes.Buffer\n\t\tbrw = brotli.NewWriter(&expectedBytes)\n\t\t_, err = brw.Write([]byte(expectedString))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error writing gzip: %v\", err)\n\t\t}\n\t\tif err = brw.Close(); err != nil {\n\t\t\tt.Fatalf(\"unexpected error closing brotli writer: %v\", err)\n\t\t}\n\t\texpectedLength := len(expectedBytes.Bytes())\n\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(&buf),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html, charset=utf-8\")\n\t\tr.Header.Set(\"Content-Encoding\", \"br\")\n\t\tr.Header.Set(\"Content-Length\", fmt.Sprintf(\"%d\", expectedLength))\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\terr = h.modifyResponse(r)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif r.Header.Get(\"Content-Length\") != fmt.Sprintf(\"%d\", expectedLength) {\n\t\t\tt.Errorf(\"expected content length to be %d, got %v\", expectedLength, r.Header.Get(\"Content-Length\"))\n\t\t}\n\n\t\tactualBody, err := io.ReadAll(brotli.NewReader(r.Body))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error reading response: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(expectedString, string(actualBody)); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t})\n\tt.Run(\"stream: body tags get the script inserted\", func(t *testing.T) {\n\t\t// Arrange\n\t\treqReader, reqWriter := io.Pipe()\n\t\tr := &http.Response{\n\t\t\tBody:   reqReader,\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html; charset=utf-8\")\n\t\tr.Header.Set(\"Transfer-Encoding\", \"chunked\")\n\n\t\texpectedString, err := insertScriptTagIntoBody(\"\", `<html><head></head><body></body></html>`)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error inserting script: %v\", err)\n\t\t}\n\t\tif !strings.Contains(expectedString, getScriptTag(t, \"\")) {\n\t\t\tt.Fatalf(\"expected the script tag to be inserted, but it wasn't: %q\", expectedString)\n\t\t}\n\n\t\t// Act\n\t\tlog := slog.New(slog.NewJSONHandler(os.Stdout, nil))\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\tif err := h.modifyResponse(r); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\tstreamingGap := 100 * time.Millisecond\n\t\tvar writerErr1, writerErr2, reqWriterErr error\n\t\tgo func() {\n\t\t\t_, writerErr1 = io.WriteString(reqWriter, `<html><head></head><body>`)\n\t\t\ttime.Sleep(streamingGap) // simulate streaming\n\t\t\t_, writerErr2 = io.WriteString(reqWriter, `</body></html>`)\n\t\t\treqWriterErr = reqWriter.Close()\n\t\t}()\n\n\t\t// Assert\n\t\tif got := r.Header.Get(\"Content-Length\"); got != \"\" {\n\t\t\tt.Errorf(\"expected Content-Length to be cleared for streaming, got %q\", got)\n\t\t}\n\n\t\t// Read the response body as it comes in, and look for at least one gap of >streamingGap between tokens.\n\t\tlastTime := time.Now()\n\t\tlargestGap := time.Duration(0)\n\t\tsBB := &strings.Builder{}\n\t\tz := html.NewTokenizer(r.Body)\n\ttokenLoop:\n\t\tfor {\n\t\t\ttt := z.Next()\n\t\t\tif since := time.Since(lastTime); since > largestGap {\n\t\t\t\tlargestGap = since\n\t\t\t}\n\t\t\tlastTime = time.Now()\n\n\t\t\tswitch tt {\n\t\t\tcase html.ErrorToken:\n\t\t\t\tif z.Err() == io.EOF {\n\t\t\t\t\tbreak tokenLoop\n\t\t\t\t}\n\t\t\t\tt.Error(\"unexpected error token:\", z.Err())\n\t\t\tdefault:\n\t\t\t\tif _, err := sBB.Write([]byte(z.Token().String())); err != nil {\n\t\t\t\t\tt.Error(\"unexpected error writing token:\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif diff := cmp.Diff(expectedString, sBB.String()); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected response body (-got +want):\\n%s\", diff)\n\t\t}\n\t\tif largestGap < streamingGap {\n\t\t\tt.Errorf(\"expected at least one gap of >%v between tokens, got largest gap of %v\", streamingGap, largestGap)\n\t\t}\n\n\t\tif writerErr1 != nil {\n\t\t\tt.Errorf(\"unexpected error writing part 1 of response: %v\", writerErr1)\n\t\t}\n\t\tif writerErr2 != nil {\n\t\t\tt.Errorf(\"unexpected error writing part 2 of response: %v\", writerErr2)\n\t\t}\n\t\tif reqWriterErr != nil {\n\t\t\tt.Errorf(\"unexpected error closing request writer: %v\", reqWriterErr)\n\t\t}\n\t})\n\tt.Run(\"notify-proxy: sending POST request to /_templ/reload/events should receive reload sse event\", func(t *testing.T) {\n\t\t// Arrange 1: create a test proxy server.\n\t\tdummyHandler := func(w http.ResponseWriter, r *http.Request) {}\n\t\tdummyServer := httptest.NewServer(http.HandlerFunc(dummyHandler))\n\t\tdefer dummyServer.Close()\n\n\t\tu, err := url.Parse(dummyServer.URL)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error parsing URL: %v\", err)\n\t\t}\n\t\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\t\thandler := New(log, \"http\", \"0.0.0.0\", 0, u)\n\t\tproxyServer := httptest.NewServer(handler)\n\t\tdefer proxyServer.Close()\n\n\t\tu2, err := url.Parse(proxyServer.URL)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error parsing URL: %v\", err)\n\t\t}\n\t\tport, err := strconv.Atoi(u2.Port())\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error parsing port: %v\", err)\n\t\t}\n\n\t\t// Arrange 2: start a goroutine to listen for sse events.\n\t\tctx := context.Background()\n\t\tctx, cancel := context.WithTimeout(ctx, 3*time.Second)\n\t\tdefer cancel()\n\n\t\terrChan := make(chan error)\n\t\tsseRespCh := make(chan string)\n\t\tsseListening := make(chan bool) // Coordination channel that ensures the SSE listener is started before notifying the proxy.\n\t\tgo func() {\n\t\t\treq, err := http.NewRequestWithContext(ctx, \"GET\", fmt.Sprintf(\"%s/_templ/reload/events\", proxyServer.URL), nil)\n\t\t\tif err != nil {\n\t\t\t\terrChan <- err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresp, err := http.DefaultClient.Do(req)\n\t\t\tif err != nil {\n\t\t\t\terrChan <- err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdefer func() {\n\t\t\t\t_ = resp.Body.Close()\n\t\t\t}()\n\n\t\t\tsseListening <- true\n\t\t\tlines := []string{}\n\t\t\tscanner := bufio.NewScanner(resp.Body)\n\t\t\tfor scanner.Scan() {\n\t\t\t\tlines = append(lines, scanner.Text())\n\t\t\t\tif scanner.Text() == \"data: reload\" {\n\t\t\t\t\tsseRespCh <- strings.Join(lines, \"\\n\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\terr = scanner.Err()\n\t\t\tif err != nil {\n\t\t\t\terrChan <- err\n\t\t\t\treturn\n\t\t\t}\n\t\t}()\n\n\t\t// Act: notify the proxy.\n\t\tselect { // Either SSE is listening or an error occurred.\n\t\tcase <-sseListening:\n\t\t\terr = NotifyProxy(u2.Hostname(), port)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error notifying proxy: %v\", err)\n\t\t\t}\n\t\tcase err := <-errChan:\n\t\t\tif err == nil {\n\t\t\t\tt.Fatalf(\"unexpected sse response: %v\", err)\n\t\t\t}\n\t\t}\n\n\t\t// Assert.\n\t\tselect { // Either SSE has a expected response or an error or timeout occurred.\n\t\tcase resp := <-sseRespCh:\n\t\t\tif !strings.Contains(resp, \"event: message\\ndata: reload\") {\n\t\t\t\tt.Errorf(\"expected sse reload event to be received, got: %q\", resp)\n\t\t\t}\n\t\tcase err := <-errChan:\n\t\t\tif err == nil {\n\t\t\t\tt.Fatalf(\"unexpected sse response: %v\", err)\n\t\t\t}\n\t\tcase <-ctx.Done():\n\t\t\tt.Fatalf(\"timeout waiting for sse response\")\n\t\t}\n\t})\n\tt.Run(\"unsupported encodings result in a warning\", func(t *testing.T) {\n\t\t// Arrange\n\t\tr := &http.Response{\n\t\t\tBody:   io.NopCloser(bytes.NewReader([]byte(\"<p>Data</p>\"))),\n\t\t\tHeader: make(http.Header),\n\t\t\tRequest: &http.Request{\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"example.com\",\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tr.Header.Set(\"Content-Type\", \"text/html, charset=utf-8\")\n\t\tr.Header.Set(\"Content-Encoding\", \"weird-encoding\")\n\n\t\t// Act\n\t\tlh := newTestLogHandler(slog.LevelInfo)\n\t\tlog := slog.New(lh)\n\t\th := New(log, \"http\", \"127.0.0.1\", 7474, &url.URL{Scheme: \"http\", Host: \"example.com\"})\n\t\terr := h.modifyResponse(r)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\t// Assert\n\t\tif len(lh.records) != 1 {\n\t\t\tvar sb strings.Builder\n\t\t\tfor _, record := range lh.records {\n\t\t\t\tsb.WriteString(record.Message)\n\t\t\t\tsb.WriteString(\"\\n\")\n\t\t\t}\n\t\t\tt.Fatalf(\"expected 1 log entry, but got %d: \\n%s\", len(lh.records), sb.String())\n\t\t}\n\t\trecord := lh.records[0]\n\t\tif record.Message != unsupportedContentEncoding {\n\t\t\tt.Errorf(\"expected warning message %q, got %q\", unsupportedContentEncoding, record.Message)\n\t\t}\n\t\tif record.Level != slog.LevelWarn {\n\t\t\tt.Errorf(\"expected warning, got level %v\", record.Level)\n\t\t}\n\t})\n}\n\nfunc newTestLogHandler(level slog.Level) *testLogHandler {\n\treturn &testLogHandler{\n\t\tm:       new(sync.Mutex),\n\t\trecords: nil,\n\t\tlevel:   level,\n\t}\n}\n\ntype testLogHandler struct {\n\tm       *sync.Mutex\n\trecords []slog.Record\n\tlevel   slog.Level\n}\n\nfunc (h *testLogHandler) Enabled(ctx context.Context, l slog.Level) bool {\n\treturn l >= h.level\n}\n\nfunc (h *testLogHandler) Handle(ctx context.Context, r slog.Record) error {\n\th.m.Lock()\n\tdefer h.m.Unlock()\n\tif r.Level < h.level {\n\t\treturn nil\n\t}\n\th.records = append(h.records, r)\n\treturn nil\n}\n\nfunc (h *testLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {\n\treturn h\n}\n\nfunc (h *testLogHandler) WithGroup(name string) slog.Handler {\n\treturn h\n}\n\nfunc TestParseNonce(t *testing.T) {\n\tfor _, tc := range []struct {\n\t\tname     string\n\t\tcsp      string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"empty csp\",\n\t\t\tcsp:      \"\",\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"simple csp\",\n\t\t\tcsp:      \"script-src 'nonce-oLhVst3hTAcxI734qtB0J9Qc7W4qy09C'\",\n\t\t\texpected: \"oLhVst3hTAcxI734qtB0J9Qc7W4qy09C\",\n\t\t},\n\t\t{\n\t\t\tname:     \"simple csp without single quote\",\n\t\t\tcsp:      \"script-src nonce-oLhVst3hTAcxI734qtB0J9Qc7W4qy09C\",\n\t\t\texpected: \"oLhVst3hTAcxI734qtB0J9Qc7W4qy09C\",\n\t\t},\n\t\t{\n\t\t\tname:     \"complete csp\",\n\t\t\tcsp:      \"default-src 'self'; frame-ancestors 'self'; form-action 'self'; script-src 'strict-dynamic' 'nonce-4VOtk0Uo1l7pwtC';\",\n\t\t\texpected: \"4VOtk0Uo1l7pwtC\",\n\t\t},\n\t\t{\n\t\t\tname:     \"mdn example 1\",\n\t\t\tcsp:      \"default-src 'self'\",\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"mdn example 2\",\n\t\t\tcsp:      \"default-src 'self' *.trusted.com\",\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"mdn example 3\",\n\t\t\tcsp:      \"default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com\",\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"mdn example 3 multiple sources\",\n\t\t\tcsp:      \"default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com foo.com 'strict-dynamic' 'nonce-4VOtk0Uo1l7pwtC'\",\n\t\t\texpected: \"4VOtk0Uo1l7pwtC\",\n\t\t},\n\t} {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tnonce := parseNonce(tc.csp)\n\t\t\tif nonce != tc.expected {\n\t\t\t\tt.Errorf(\"expected nonce to be %s, but got %s\", tc.expected, nonce)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestStreamInsertAfterBodyOpen(t *testing.T) {\n\tt.Run(\"script tags with special characters are not escaped\", func(t *testing.T) {\n\t\tinput := `<html>\n<head><title>Test</title></head>\n<body>\n<script>\nvar x = localStorage.getItem('test');\nvar y = true && false;\n</script>\n</body>\n</html>`\n\n\t\tvar output bytes.Buffer\n\t\terr := streamInsertAfterBodyOpen(\"\", strings.NewReader(input), &output)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\tresult := output.String()\n\n\t\tif !strings.Contains(result, \"localStorage.getItem('test')\") {\n\t\t\tt.Errorf(\"expected single quotes to not be escaped, got: %s\", result)\n\t\t}\n\t\tif strings.Contains(result, \"&#39;\") {\n\t\t\tt.Errorf(\"single quotes should not be escaped to &#39;, got: %s\", result)\n\t\t}\n\t\tif !strings.Contains(result, \"true && false\") {\n\t\t\tt.Errorf(\"expected && to not be escaped, got: %s\", result)\n\t\t}\n\t\tif strings.Contains(result, \"&amp;&amp;\") {\n\t\t\tt.Errorf(\"&& should not be escaped to &amp;&amp;, got: %s\", result)\n\t\t}\n\t})\n\n\tt.Run(\"large HTML with script tags maintains character integrity\", func(t *testing.T) {\n\t\tvar inputBuilder strings.Builder\n\t\tinputBuilder.WriteString(`<html>\n<head><title>Test</title></head>\n<body>\n<script>\nvar x = localStorage.getItem('test');\nvar y = true && false;\nalert(\"test\");\n</script>`)\n\t\tfor i := range 50 {\n\t\t\tinputBuilder.WriteString(fmt.Sprintf(\"<div>%d padding</div>\\n\", i))\n\t\t}\n\t\tinputBuilder.WriteString(\"</body></html>\")\n\t\tinput := inputBuilder.String()\n\n\t\tvar output bytes.Buffer\n\t\terr := streamInsertAfterBodyOpen(\"\", strings.NewReader(input), &output)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\tresult := output.String()\n\n\t\tif !strings.Contains(result, \"localStorage.getItem('test')\") {\n\t\t\tt.Errorf(\"expected single quotes to not be escaped in large document\")\n\t\t}\n\t\tif strings.Contains(result, \"&#39;\") {\n\t\t\tt.Errorf(\"single quotes should not be escaped to &#39; in large document\")\n\t\t}\n\t\tif !strings.Contains(result, \"true && false\") {\n\t\t\tt.Errorf(\"expected && to not be escaped in large document\")\n\t\t}\n\t\tif strings.Contains(result, \"&amp;&amp;\") {\n\t\t\tt.Errorf(\"&& should not be escaped to &amp;&amp; in large document\")\n\t\t}\n\t\tif !strings.Contains(result, `alert(\"test\")`) {\n\t\t\tt.Errorf(\"expected double quotes to not be escaped in large document\")\n\t\t}\n\t})\n\n\tt.Run(\"script with nonce attribute is inserted correctly\", func(t *testing.T) {\n\t\tinput := `<html><body><p>Content</p></body></html>`\n\t\tnonce := \"test-nonce-123\"\n\n\t\tvar output bytes.Buffer\n\t\terr := streamInsertAfterBodyOpen(nonce, strings.NewReader(input), &output)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\tresult := output.String()\n\n\t\tif !strings.Contains(result, `nonce=\"`+nonce+`\"`) {\n\t\t\tt.Errorf(\"expected nonce attribute to be present with value %s, got: %s\", nonce, result)\n\t\t}\n\t\tif !strings.Contains(result, `src=\"/_templ/reload/script.js\"`) {\n\t\t\tt.Errorf(\"expected script src to be present, got: %s\", result)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/proxy/script.js",
    "content": "(function() {\n  let templ_reloadSrc = window.templ_reloadSrc || new EventSource(\"/_templ/reload/events\");\n  templ_reloadSrc.onmessage = (event) => {\n    if (event && event.data === \"reload\") {\n      window.location.reload();\n    }\n  };\n  window.templ_reloadSrc = templ_reloadSrc;\n  window.onbeforeunload = () => window.templ_reloadSrc.close();\n})();\n"
  },
  {
    "path": "cmd/templ/generatecmd/run/run_test.go",
    "content": "package run_test\n\nimport (\n\t\"context\"\n\t\"embed\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/run\"\n)\n\n//go:embed testprogram/*\nvar testprogram embed.FS\n\nfunc TestGoRun(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"Skipping test in short mode.\")\n\t}\n\n\t// Copy testprogram to a temporary directory.\n\tdir, err := os.MkdirTemp(\"\", \"testprogram\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to make test dir: %v\", err)\n\t}\n\tfiles, err := testprogram.ReadDir(\"testprogram\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read embedded dir: %v\", err)\n\t}\n\tfor _, file := range files {\n\t\tsrcFileName := \"testprogram/\" + file.Name()\n\t\tsrcData, err := testprogram.ReadFile(srcFileName)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to read src file %q: %v\", srcFileName, err)\n\t\t}\n\t\ttgtFileName := filepath.Join(dir, file.Name())\n\t\tif err = os.WriteFile(tgtFileName, srcData, 0644); err != nil {\n\t\t\tt.Fatalf(\"failed to write tgt file %q: %v\", tgtFileName, err)\n\t\t}\n\t}\n\t// Rename the go.mod.embed file to go.mod.\n\tif err := os.Rename(filepath.Join(dir, \"go.mod.embed\"), filepath.Join(dir, \"go.mod\")); err != nil {\n\t\tt.Fatalf(\"failed to rename go.mod.embed: %v\", err)\n\t}\n\n\ttests := []struct {\n\t\tname string\n\t\tcmd  string\n\t}{\n\t\t{\n\t\t\tname: \"Well behaved programs get shut down\",\n\t\t\tcmd:  \"go run .\",\n\t\t},\n\t\t{\n\t\t\tname: \"Badly behaved programs get shut down\",\n\t\t\tcmd:  \"go run . -badly-behaved\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\t\t\tcmd, err := run.Run(ctx, dir, tt.cmd)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to run program: %v\", err)\n\t\t\t}\n\n\t\t\ttime.Sleep(1 * time.Second)\n\n\t\t\tpid := cmd.Process.Pid\n\n\t\t\tif err := run.KillAll(); err != nil {\n\t\t\t\tt.Fatalf(\"failed to kill all: %v\", err)\n\t\t\t}\n\n\t\t\t// Check the parent process is no longer running.\n\t\t\tif err := cmd.Process.Signal(os.Signal(syscall.Signal(0))); err == nil {\n\t\t\t\tt.Fatalf(\"process %d is still running\", pid)\n\t\t\t}\n\t\t\t// Check that the child was stopped.\n\t\t\tbody, err := readResponse(\"http://localhost:7777\")\n\t\t\tif err == nil {\n\t\t\t\tt.Fatalf(\"child process is still running: %s\", body)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc readResponse(url string) (body string, err error) {\n\tresp, err := http.Get(url)\n\tif err != nil {\n\t\treturn body, err\n\t}\n\tb, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\t_ = resp.Body.Close()\n\t\treturn body, err\n\t}\n\tif err = resp.Body.Close(); err != nil {\n\t\treturn body, err\n\t}\n\treturn string(b), nil\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/run/run_unix.go",
    "content": "//go:build unix\n\npackage run\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n)\n\nvar (\n\tm       = &sync.Mutex{}\n\trunning = map[string]*exec.Cmd{}\n)\n\nfunc KillAll() (err error) {\n\tm.Lock()\n\tdefer m.Unlock()\n\tvar errs []error\n\tfor _, cmd := range running {\n\t\tif err := kill(cmd); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"failed to kill process %d: %w\", cmd.Process.Pid, err))\n\t\t}\n\t}\n\trunning = map[string]*exec.Cmd{}\n\treturn errors.Join(errs...)\n}\n\nfunc kill(cmd *exec.Cmd) (err error) {\n\terrs := make([]error, 4)\n\terrs[0] = ignoreExited(cmd.Process.Signal(syscall.SIGINT))\n\terrs[1] = ignoreExited(cmd.Process.Signal(syscall.SIGTERM))\n\terrs[2] = ignoreExited(cmd.Wait())\n\terrs[3] = ignoreExited(syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL))\n\treturn errors.Join(errs...)\n}\n\nfunc ignoreExited(err error) error {\n\tif errors.Is(err, syscall.ESRCH) {\n\t\treturn nil\n\t}\n\t// Ignore *exec.ExitError\n\tif _, ok := err.(*exec.ExitError); ok {\n\t\treturn nil\n\t}\n\treturn err\n}\n\nfunc Run(ctx context.Context, workingDir string, input string) (cmd *exec.Cmd, err error) {\n\tm.Lock()\n\tdefer m.Unlock()\n\tcmd, ok := running[input]\n\tif ok {\n\t\tif err := kill(cmd); err != nil {\n\t\t\treturn cmd, fmt.Errorf(\"failed to kill process %d: %w\", cmd.Process.Pid, err)\n\t\t}\n\n\t\tdelete(running, input)\n\t}\n\tparts := strings.Fields(input)\n\texecutable := parts[0]\n\targs := []string{}\n\tif len(parts) > 1 {\n\t\targs = append(args, parts[1:]...)\n\t}\n\n\tcmd = exec.CommandContext(ctx, executable, args...)\n\t// Wait for the process to finish gracefully before termination.\n\tcmd.WaitDelay = time.Second * 3\n\tcmd.Env = os.Environ()\n\tcmd.Dir = workingDir\n\tcmd.Stdin = os.Stdin\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\tcmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}\n\trunning[input] = cmd\n\terr = cmd.Start()\n\treturn\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/run/run_windows.go",
    "content": "//go:build windows\n\npackage run\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\nvar (\n\tm       = &sync.Mutex{}\n\trunning = map[string]*exec.Cmd{}\n)\n\nfunc KillAll() (err error) {\n\tm.Lock()\n\tdefer m.Unlock()\n\tfor _, cmd := range running {\n\t\tkill := exec.Command(\"TASKKILL\", \"/T\", \"/F\", \"/PID\", strconv.Itoa(cmd.Process.Pid))\n\t\tkill.Stderr = os.Stderr\n\t\tkill.Stdout = os.Stdout\n\t\terr := kill.Run()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\trunning = map[string]*exec.Cmd{}\n\treturn\n}\n\nfunc Stop(cmd *exec.Cmd) (err error) {\n\tkill := exec.Command(\"TASKKILL\", \"/T\", \"/F\", \"/PID\", strconv.Itoa(cmd.Process.Pid))\n\tkill.Stderr = os.Stderr\n\tkill.Stdout = os.Stdout\n\treturn kill.Run()\n}\n\nfunc Run(ctx context.Context, workingDir string, input string) (cmd *exec.Cmd, err error) {\n\tm.Lock()\n\tdefer m.Unlock()\n\tcmd, ok := running[input]\n\tif ok {\n\t\tkill := exec.Command(\"TASKKILL\", \"/T\", \"/F\", \"/PID\", strconv.Itoa(cmd.Process.Pid))\n\t\tkill.Stderr = os.Stderr\n\t\tkill.Stdout = os.Stdout\n\t\terr := kill.Run()\n\t\tif err != nil {\n\t\t\treturn cmd, err\n\t\t}\n\t\tdelete(running, input)\n\t}\n\tparts := strings.Fields(input)\n\texecutable := parts[0]\n\targs := []string{}\n\tif len(parts) > 1 {\n\t\targs = append(args, parts[1:]...)\n\t}\n\n\tcmd = exec.Command(executable, args...)\n\tcmd.Env = os.Environ()\n\tcmd.Dir = workingDir\n\tcmd.Stdin = os.Stdin\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\trunning[input] = cmd\n\terr = cmd.Start()\n\treturn\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/run/testprogram/go.mod.embed",
    "content": "module testprogram\n\ngo 1.23\n"
  },
  {
    "path": "cmd/templ/generatecmd/run/testprogram/main.go",
    "content": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n)\n\n// This is a test program. It is used only to test the behaviour of the run package.\n// The run package is supposed to be able to run and stop programs. Those programs may start\n// child processes, which should also be stopped when the parent program is stopped.\n\n// For example, running `go run .` will compile an executable and run it.\n\n// So, this program does nothing. It just waits for a signal to stop.\n\n// In \"Well behaved\" mode, the program will stop when it receives a signal.\n// In \"Badly behaved\" mode, the program will ignore the signal and continue running.\n\n// The run package should be able to stop the program in both cases.\n\nvar badlyBehavedFlag = flag.Bool(\"badly-behaved\", false, \"If set, the program will ignore the stop signal and continue running.\")\n\nfunc main() {\n\tflag.Parse()\n\n\tmode := \"Well behaved\"\n\tif *badlyBehavedFlag {\n\t\tmode = \"Badly behaved\"\n\t}\n\tfmt.Printf(\"%s process %d started.\\n\", mode, os.Getpid())\n\n\t// Start a web server on a known port so that we can check that this process is\n\t// not running, when it's been started as a child process, and we don't know\n\t// its pid.\n\tgo func() {\n\t\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\t\t_, _ = fmt.Fprintf(w, \"%d\", os.Getpid())\n\t\t})\n\t\terr := http.ListenAndServe(\"127.0.0.1:7777\", nil)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error running web server: %v\\n\", err)\n\t\t}\n\t}()\n\n\tsigs := make(chan os.Signal, 1)\n\tif !*badlyBehavedFlag {\n\t\tsignal.Notify(sigs, os.Interrupt, syscall.SIGTERM)\n\t}\n\tfor {\n\t\tselect {\n\t\tcase <-sigs:\n\t\t\tfmt.Printf(\"Process %d received signal. Stopping.\\n\", os.Getpid())\n\t\t\treturn\n\t\tcase <-time.After(1 * time.Second):\n\t\t\tfmt.Printf(\"Process %d still running...\\n\", os.Getpid())\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/sse/server.go",
    "content": "package sse\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\nfunc New() *Handler {\n\treturn &Handler{\n\t\tm:        new(sync.Mutex),\n\t\trequests: map[int64]chan event{},\n\t}\n}\n\ntype Handler struct {\n\tm        *sync.Mutex\n\tcounter  int64\n\trequests map[int64]chan event\n}\n\ntype event struct {\n\tType string\n\tData string\n}\n\n// Send an event to all connected clients.\nfunc (s *Handler) Send(eventType string, data string) {\n\ts.m.Lock()\n\tdefer s.m.Unlock()\n\tfor _, f := range s.requests {\n\t\tf := f\n\t\tgo func(f chan event) {\n\t\t\tf <- event{\n\t\t\t\tType: eventType,\n\t\t\t\tData: data,\n\t\t\t}\n\t\t}(f)\n\t}\n}\n\nfunc (s *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tw.Header().Set(\"Access-Control-Allow-Origin\", \"*\")\n\tw.Header().Set(\"Access-Control-Allow-Headers\", \"Content-Type\")\n\tw.Header().Set(\"Content-Type\", \"text/event-stream\")\n\tw.Header().Set(\"Cache-Control\", \"no-cache\")\n\tw.Header().Set(\"Connection\", \"keep-alive\")\n\n\tid := atomic.AddInt64(&s.counter, 1)\n\ts.m.Lock()\n\tevents := make(chan event)\n\ts.requests[id] = events\n\ts.m.Unlock()\n\tdefer func() {\n\t\ts.m.Lock()\n\t\tdefer s.m.Unlock()\n\t\tdelete(s.requests, id)\n\t\tclose(events)\n\t}()\n\n\ttimer := time.NewTimer(0)\nloop:\n\tfor {\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\tif _, err := fmt.Fprintf(w, \"event: message\\ndata: ping\\n\\n\"); err != nil {\n\t\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttimer.Reset(time.Second * 5)\n\t\tcase e := <-events:\n\t\t\tif _, err := fmt.Fprintf(w, \"event: %s\\ndata: %s\\n\\n\", e.Type, e.Data); err != nil {\n\t\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-r.Context().Done():\n\t\t\tbreak loop\n\t\t}\n\t\tw.(http.Flusher).Flush()\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/symlink/symlink_test.go",
    "content": "package symlink\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/cmd/templ/generatecmd\"\n\t\"github.com/a-h/templ/cmd/templ/testproject\"\n)\n\nfunc TestSymlink(t *testing.T) {\n\tt.Run(\"can generate if root is symlink\", func(t *testing.T) {\n\t\t// templ generate -f templates.templ\n\t\tdir, err := testproject.Create(\"github.com/a-h/templ/cmd/templ/testproject\")\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to create test project: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := os.RemoveAll(dir); err != nil {\n\t\t\t\tt.Errorf(\"failed to remove test project directory: %v\", err)\n\t\t\t}\n\t\t}()\n\n\t\tsymlinkPath := dir + \"-symlink\"\n\t\terr = os.Symlink(dir, symlinkPath)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to create dir symlink: %v\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err = os.Remove(symlinkPath); err != nil {\n\t\t\t\tt.Errorf(\"failed to remove symlink directory: %v\", err)\n\t\t\t}\n\t\t}()\n\n\t\t// Delete the templates_templ.go file to ensure it is generated.\n\t\terr = os.Remove(path.Join(symlinkPath, \"templates_templ.go\"))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to remove templates_templ.go: %v\", err)\n\t\t}\n\n\t\t// Run the generate command.\n\t\terr = generatecmd.Run(context.Background(), io.Discard, io.Discard, []string{\"-path\", symlinkPath})\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to run generate command: %v\", err)\n\t\t}\n\n\t\t// Check the templates_templ.go file was created.\n\t\t_, err = os.Stat(path.Join(symlinkPath, \"templates_templ.go\"))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"templates_templ.go was not created: %v\", err)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/test-eventhandler/eventhandler_test.go",
    "content": "package testeventhandler\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"go/scanner\"\n\t\"go/token\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/cmd/templ/generatecmd\"\n\t\"github.com/a-h/templ/generator\"\n\t\"github.com/fsnotify/fsnotify\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\n// extractErrorList unwraps errors until it finds a scanner.ErrorList\nfunc extractErrorList(err error) (scanner.ErrorList, bool) {\n\tif err == nil {\n\t\treturn nil, false\n\t}\n\n\tif list, ok := err.(scanner.ErrorList); ok {\n\t\treturn list, true\n\t}\n\n\treturn extractErrorList(errors.Unwrap(err))\n}\n\nfunc TestErrorLocationMapping(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\trawFileName    string\n\t\terrorPositions []token.Position\n\t}{\n\t\t{\n\t\t\tname:        \"single error outputs location in srcFile\",\n\t\t\trawFileName: \"single_error.templ.error\",\n\t\t\terrorPositions: []token.Position{\n\t\t\t\t{Offset: 46, Line: 3, Column: 20},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:        \"multiple errors all output locations in srcFile\",\n\t\t\trawFileName: \"multiple_errors.templ.error\",\n\t\t\terrorPositions: []token.Position{\n\t\t\t\t{Offset: 41, Line: 3, Column: 15},\n\t\t\t\t{Offset: 101, Line: 7, Column: 22},\n\t\t\t\t{Offset: 126, Line: 10, Column: 1},\n\t\t\t},\n\t\t},\n\t}\n\n\tslog := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{}))\n\tvar fw generatecmd.FileWriterFunc\n\tfseh := generatecmd.NewFSEventHandler(slog, \".\", false, []generator.GenerateOpt{}, false, false, fw, false)\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\t// The raw files cannot end in .templ because they will cause the generator to fail. Instead,\n\t\t\t// we create a tmp file that ends in .templ only for the duration of the test.\n\t\t\trawFile, err := os.Open(test.rawFileName)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"Failed to open file %s: %v\", test.rawFileName, err)\n\t\t\t}\n\t\t\tdefer func() {\n\t\t\t\tif err = rawFile.Close(); err != nil {\n\t\t\t\t\tt.Fatalf(\"Failed to close raw file %s: %v\", test.rawFileName, err)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tfile, err := os.CreateTemp(\"\", fmt.Sprintf(\"*%s.templ\", test.rawFileName))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"Failed to create a tmp file at %s: %v\", file.Name(), err)\n\t\t\t}\n\t\t\ttempFileName := file.Name()\n\t\t\tdefer func() {\n\t\t\t\t_ = file.Close()\n\t\t\t\tif err := os.Remove(tempFileName); err != nil {\n\t\t\t\t\tt.Logf(\"Warning: Failed to remove tmp file %s: %v\", tempFileName, err)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tif _, err = io.Copy(file, rawFile); err != nil {\n\t\t\t\tt.Fatalf(\"Failed to copy contents from raw file %s to tmp %s: %v\", test.rawFileName, tempFileName, err)\n\t\t\t}\n\n\t\t\t// Ensure file is synced to disk and file pointer is at the beginning\n\t\t\tif err = file.Sync(); err != nil {\n\t\t\t\tt.Fatalf(\"Failed to sync file: %v\", err)\n\t\t\t}\n\n\t\t\tevent := fsnotify.Event{Name: tempFileName, Op: fsnotify.Write}\n\t\t\t_, err = fseh.HandleEvent(context.Background(), event)\n\t\t\tif err == nil {\n\t\t\t\tt.Fatal(\"Expected an error but none was thrown\")\n\t\t\t}\n\n\t\t\tlist, ok := extractErrorList(err)\n\t\t\tif !ok {\n\t\t\t\tt.Fatal(\"Failed to extract ErrorList from error\")\n\t\t\t}\n\n\t\t\tif len(list) != len(test.errorPositions) {\n\t\t\t\tt.Fatalf(\"Expected %d errors but got %d\", len(test.errorPositions), len(list))\n\t\t\t}\n\n\t\t\tfor i, err := range list {\n\t\t\t\texpected := test.errorPositions[i]\n\t\t\t\texpected.Filename = tempFileName\n\n\t\t\t\tif diff := cmp.Diff(expected, err.Pos); diff != \"\" {\n\t\t\t\t\tt.Errorf(\"Error position mismatch (-expected +actual):\\n%s\", diff)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/test-eventhandler/multiple_errors.templ.error",
    "content": "package testeventhandler\n\nfunc invalid(a: string) string {\n    return \"foo\"\n}\n\ntempl multipleError(a: string) {\n    <div/>\n}\nl\n"
  },
  {
    "path": "cmd/templ/generatecmd/test-eventhandler/single_error.templ.error",
    "content": "package testeventhandler\n\ntempl singleError(a: string) {\n    <div/>\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/testwatch/generate_test.go",
    "content": "package testwatch\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"embed\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/cmd/templ/generatecmd\"\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/modcheck\"\n\t\"github.com/a-h/templ/internal/htmlfind\"\n\t\"golang.org/x/net/html\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n//go:embed testdata/*\nvar testdata embed.FS\n\nfunc createTestProject(moduleRoot string) (dir string, err error) {\n\tdir, err = os.MkdirTemp(\"\", \"templ_watch_test_*\")\n\tif err != nil {\n\t\treturn dir, fmt.Errorf(\"failed to make test dir: %w\", err)\n\t}\n\tfiles, err := testdata.ReadDir(\"testdata\")\n\tif err != nil {\n\t\treturn dir, fmt.Errorf(\"failed to read embedded dir: %w\", err)\n\t}\n\tfor _, file := range files {\n\t\tsrc := filepath.Join(\"testdata\", file.Name())\n\t\tdata, err := testdata.ReadFile(src)\n\t\tif err != nil {\n\t\t\treturn dir, fmt.Errorf(\"failed to read file: %w\", err)\n\t\t}\n\n\t\ttarget := filepath.Join(dir, file.Name())\n\t\tif file.Name() == \"go.mod.embed\" {\n\t\t\tdata = bytes.ReplaceAll(data, []byte(\"{moduleRoot}\"), []byte(moduleRoot))\n\t\t\ttarget = filepath.Join(dir, \"go.mod\")\n\t\t}\n\t\terr = os.WriteFile(target, data, 0660)\n\t\tif err != nil {\n\t\t\treturn dir, fmt.Errorf(\"failed to copy file: %w\", err)\n\t\t}\n\t}\n\treturn dir, nil\n}\n\nfunc replaceInFile(name, src, tgt string) error {\n\tdata, err := os.ReadFile(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tupdated := strings.ReplaceAll(string(data), src, tgt)\n\treturn os.WriteFile(name, []byte(updated), 0660)\n}\n\nfunc getPort() (port int, err error) {\n\tvar a *net.TCPAddr\n\ta, err = net.ResolveTCPAddr(\"tcp\", \"localhost:0\")\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to resolve TCP address: %w\", err)\n\t}\n\tl, err := net.ListenTCP(\"tcp\", a)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to listen on TCP: %w\", err)\n\t}\n\treturn l.Addr().(*net.TCPAddr).Port, l.Close()\n}\n\nfunc getHTML(url string) (n *html.Node, err error) {\n\tresp, err := http.Get(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get %q: %w\", url, err)\n\t}\n\tdefer func() {\n\t\t_ = resp.Body.Close()\n\t}()\n\treturn html.Parse(resp.Body)\n}\n\nfunc TestCanAccessDirect(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\targs, teardown, err := Setup(false)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\n\t// Assert.\n\tdoc, err := getHTML(args.AppURL)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read HTML: %v\", err)\n\t}\n\tcountElements := htmlfind.All(doc, htmlfind.Element(\"div\", htmlfind.Attr(\"data-testid\", \"count\")))\n\tif len(countElements) != 1 {\n\t\tt.Fatalf(\"expected 1 count element, got %d\", len(countElements))\n\t}\n\tcountText := countElements[0].FirstChild.Data\n\tactualCount, err := strconv.Atoi(countText)\n\tif err != nil {\n\t\tt.Fatalf(\"got count %q instead of integer\", countText)\n\t}\n\tif actualCount < 1 {\n\t\tt.Errorf(\"expected count >= 1, got %d\", actualCount)\n\t}\n}\n\nfunc TestCanAccessViaProxy(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\targs, teardown, err := Setup(false)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\n\t// Assert.\n\tdoc, err := getHTML(args.ProxyURL)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read HTML: %v\", err)\n\t}\n\tcountElements := htmlfind.All(doc, htmlfind.Element(\"div\", htmlfind.Attr(\"data-testid\", \"count\")))\n\tif len(countElements) != 1 {\n\t\tt.Fatalf(\"expected 1 count element, got %d\", len(countElements))\n\t}\n\tcountText := countElements[0].FirstChild.Data\n\tactualCount, err := strconv.Atoi(countText)\n\tif err != nil {\n\t\tt.Fatalf(\"got count %q instead of integer\", countText)\n\t}\n\tif actualCount < 1 {\n\t\tt.Errorf(\"expected count >= 1, got %d\", actualCount)\n\t}\n}\n\ntype Event struct {\n\tType string\n\tData string\n}\n\nfunc readSSE(ctx context.Context, url string, sse chan<- Event) (err error) {\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\treq.Header.Set(\"Cache-Control\", \"no-cache\")\n\treq.Header.Set(\"Accept\", \"text/event-stream\")\n\treq.Header.Set(\"Connection\", \"keep-alive\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar e Event\n\tscanner := bufio.NewScanner(resp.Body)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif line == \"\" {\n\t\t\tsse <- e\n\t\t\te = Event{}\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"event: \") {\n\t\t\te.Type = line[len(\"event: \"):]\n\t\t}\n\t\tif strings.HasPrefix(line, \"data: \") {\n\t\t\te.Data = line[len(\"data: \"):]\n\t\t}\n\t}\n\treturn scanner.Err()\n}\n\nfunc TestFileModificationsResultInSSEWithGzip(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\targs, teardown, err := Setup(false)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\n\t// Start the SSE check.\n\tevents := make(chan Event)\n\tvar eventsErr error\n\tgo func() {\n\t\teventsErr = readSSE(context.Background(), fmt.Sprintf(\"%s/_templ/reload/events\", args.ProxyURL), events)\n\t}()\n\n\t// Assert data is expected.\n\tdoc, err := getHTML(args.ProxyURL)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read HTML: %v\", err)\n\t}\n\tmodified := htmlfind.All(doc, htmlfind.Element(\"div\", htmlfind.Attr(\"data-testid\", \"modification\")))\n\tif len(modified) != 1 {\n\t\tt.Fatalf(\"expected 1 modification element, got %d\", len(modified))\n\t}\n\tif text := modified[0].FirstChild.Data; text != \"Original\" {\n\t\tt.Errorf(\"expected %q, got %q\", \"Original\", text)\n\t}\n\n\t// Change file.\n\ttemplFile := filepath.Join(args.AppDir, \"templates.templ\")\n\terr = replaceInFile(templFile,\n\t\t`<div data-testid=\"modification\">Original</div>`,\n\t\t`<div data-testid=\"modification\">Updated</div>`)\n\tif err != nil {\n\t\tt.Errorf(\"failed to replace text in file: %v\", err)\n\t}\n\n\t// Give the filesystem watcher a few seconds.\n\tvar reloadCount int\nloop:\n\tfor {\n\t\tselect {\n\t\tcase event := <-events:\n\t\t\tif event.Data == \"reload\" {\n\t\t\t\treloadCount++\n\t\t\t\tbreak loop\n\t\t\t}\n\t\tcase <-time.After(time.Second * 5):\n\t\t\tbreak loop\n\t\t}\n\t}\n\tif reloadCount == 0 {\n\t\tt.Error(\"failed to receive SSE about update after 5 seconds\")\n\t}\n\n\t// Check to see if there were any errors.\n\tif eventsErr != nil {\n\t\tt.Errorf(\"error reading events: %v\", err)\n\t}\n\n\t// See results in browser immediately.\n\tdoc, err = getHTML(args.ProxyURL)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read HTML: %v\", err)\n\t}\n\tmodified = htmlfind.All(doc, htmlfind.Element(\"div\", htmlfind.Attr(\"data-testid\", \"modification\")))\n\tif len(modified) != 1 {\n\t\tt.Fatalf(\"expected 1 modification element, got %d\", len(modified))\n\t}\n\tif text := modified[0].FirstChild.Data; text != \"Updated\" {\n\t\tt.Errorf(\"expected %q, got %q\", \"Updated\", text)\n\t}\n}\n\nfunc TestFileModificationsResultInSSE(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\targs, teardown, err := Setup(false)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\n\t// Start the SSE check.\n\tevents := make(chan Event)\n\tvar eventsErr error\n\tgo func() {\n\t\teventsErr = readSSE(context.Background(), fmt.Sprintf(\"%s/_templ/reload/events\", args.ProxyURL), events)\n\t}()\n\n\t// Assert data is expected.\n\tdoc, err := getHTML(args.ProxyURL)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read HTML: %v\", err)\n\t}\n\tmodified := htmlfind.All(doc, htmlfind.Element(\"div\", htmlfind.Attr(\"data-testid\", \"modification\")))\n\tif len(modified) != 1 {\n\t\tt.Fatalf(\"expected 1 modification element, got %d\", len(modified))\n\t}\n\tif text := modified[0].FirstChild.Data; text != \"Original\" {\n\t\tt.Errorf(\"expected %q, got %q\", \"Original\", text)\n\t}\n\n\t// Change file.\n\ttemplFile := filepath.Join(args.AppDir, \"templates.templ\")\n\terr = replaceInFile(templFile,\n\t\t`<div data-testid=\"modification\">Original</div>`,\n\t\t`<div data-testid=\"modification\">Updated</div>`)\n\tif err != nil {\n\t\tt.Errorf(\"failed to replace text in file: %v\", err)\n\t}\n\n\t// Give the filesystem watcher a few seconds.\n\tvar reloadCount int\nloop:\n\tfor {\n\t\tselect {\n\t\tcase event := <-events:\n\t\t\tif event.Data == \"reload\" {\n\t\t\t\treloadCount++\n\t\t\t\tbreak loop\n\t\t\t}\n\t\tcase <-time.After(time.Second * 5):\n\t\t\tbreak loop\n\t\t}\n\t}\n\tif reloadCount == 0 {\n\t\tt.Error(\"failed to receive SSE about update after 5 seconds\")\n\t}\n\n\t// Check to see if there were any errors.\n\tif eventsErr != nil {\n\t\tt.Errorf(\"error reading events: %v\", err)\n\t}\n\n\t// See results in browser immediately.\n\tdoc, err = getHTML(args.ProxyURL)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read HTML: %v\", err)\n\t}\n\tmodified = htmlfind.All(doc, htmlfind.Element(\"div\", htmlfind.Attr(\"data-testid\", \"modification\")))\n\tif len(modified) != 1 {\n\t\tt.Fatalf(\"expected 1 modification element, got %d\", len(modified))\n\t}\n\tif text := modified[0].FirstChild.Data; text != \"Updated\" {\n\t\tt.Errorf(\"expected %q, got %q\", \"Updated\", text)\n\t}\n}\n\nfunc NewTestArgs(modRoot, appDir string, appPort int, proxyBind string, proxyPort int) TestArgs {\n\treturn TestArgs{\n\t\tModRoot:   modRoot,\n\t\tAppDir:    appDir,\n\t\tAppPort:   appPort,\n\t\tAppURL:    fmt.Sprintf(\"http://localhost:%d\", appPort),\n\t\tProxyBind: proxyBind,\n\t\tProxyPort: proxyPort,\n\t\tProxyURL:  fmt.Sprintf(\"http://%s:%d\", proxyBind, proxyPort),\n\t}\n}\n\ntype TestArgs struct {\n\tModRoot   string\n\tAppDir    string\n\tAppPort   int\n\tAppURL    string\n\tProxyBind string\n\tProxyPort int\n\tProxyURL  string\n}\n\nfunc Setup(gzipEncoding bool) (args TestArgs, teardown func(t *testing.T), err error) {\n\twd, err := os.Getwd()\n\tif err != nil {\n\t\treturn args, teardown, fmt.Errorf(\"could not find working dir: %w\", err)\n\t}\n\tmoduleRoot, err := modcheck.WalkUp(wd)\n\tif err != nil {\n\t\treturn args, teardown, fmt.Errorf(\"could not find local templ go.mod file: %v\", err)\n\t}\n\n\tappDir, err := createTestProject(moduleRoot)\n\tif err != nil {\n\t\treturn args, teardown, fmt.Errorf(\"failed to create test project: %v\", err)\n\t}\n\tappPort, err := getPort()\n\tif err != nil {\n\t\treturn args, teardown, fmt.Errorf(\"failed to get available port: %v\", err)\n\t}\n\tproxyPort, err := getPort()\n\tif err != nil {\n\t\treturn args, teardown, fmt.Errorf(\"failed to get available port: %v\", err)\n\t}\n\tproxyBind := \"localhost\"\n\n\targs = NewTestArgs(moduleRoot, appDir, appPort, proxyBind, proxyPort)\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tvar wg errgroup.Group\n\twg.Go(func() error {\n\t\tcommand := fmt.Sprintf(\"go run . -port %d\", args.AppPort)\n\t\tif gzipEncoding {\n\t\t\tcommand += \" -gzip true\"\n\t\t}\n\t\treturn generatecmd.Run(ctx, io.Discard, io.Discard, []string{\"-path\", appDir, \"-watch\", \"-proxybind\", proxyBind, \"-proxyport\", strconv.Itoa(proxyPort), \"-proxy\", args.AppURL, \"-open-browser=false\", \"-cmd\", command})\n\t})\n\n\t// Wait for server to start.\n\tif err = waitForURL(args.AppURL); err != nil {\n\t\tcancel()\n\t\tcmdErr := wg.Wait()\n\t\treturn args, teardown, fmt.Errorf(\"failed to start app server: %w\", errors.Join(cmdErr, err))\n\t}\n\tif err = waitForURL(args.ProxyURL); err != nil {\n\t\tcancel()\n\t\tcmdErr := wg.Wait()\n\t\treturn args, teardown, fmt.Errorf(\"failed to start proxy server: %w\", errors.Join(cmdErr, err))\n\t}\n\n\t// Wait for exit.\n\tteardown = func(t *testing.T) {\n\t\tcancel()\n\t\tif cmdErr := wg.Wait(); cmdErr != nil {\n\t\t\tt.Errorf(\"failed to run generate cmd: %v\", cmdErr)\n\t\t}\n\t\tif err = os.RemoveAll(appDir); err != nil {\n\t\t\tt.Fatalf(\"failed to remove test dir %q: %v\", appDir, err)\n\t\t}\n\t}\n\treturn args, teardown, err\n}\n\nfunc waitForURL(url string) (err error) {\n\tvar tries int\n\tfor {\n\t\ttime.Sleep(time.Second)\n\t\tif tries > 20 {\n\t\t\treturn err\n\t\t}\n\t\ttries++\n\t\tvar resp *http.Response\n\t\tresp, err = http.Get(url)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"failed to get %q: %v\\n\", url, err)\n\t\t\tcontinue\n\t\t}\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tfmt.Printf(\"failed to get %q: %v\\n\", url, err)\n\t\t\terr = fmt.Errorf(\"expected status code %d, got %d\", http.StatusOK, resp.StatusCode)\n\t\t\tcontinue\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc TestGenerateReturnsErrors(t *testing.T) {\n\twd, err := os.Getwd()\n\tif err != nil {\n\t\tt.Fatalf(\"could not find working dir: %v\", err)\n\t}\n\tmoduleRoot, err := modcheck.WalkUp(wd)\n\tif err != nil {\n\t\tt.Fatalf(\"could not find local templ go.mod file: %v\", err)\n\t}\n\n\tappDir, err := createTestProject(moduleRoot)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create test project: %v\", err)\n\t}\n\tdefer func() {\n\t\tif err = os.RemoveAll(appDir); err != nil {\n\t\t\tt.Fatalf(\"failed to remove test dir %q: %v\", appDir, err)\n\t\t}\n\t}()\n\n\t// Break the HTML.\n\ttemplFile := filepath.Join(appDir, \"templates.templ\")\n\terr = replaceInFile(templFile,\n\t\t`<div data-testid=\"modification\">Original</div>`,\n\t\t`<div data-testid=\"modification\" -unclosed div-</div>`)\n\tif err != nil {\n\t\tt.Errorf(\"failed to replace text in file: %v\", err)\n\t}\n\n\t// Run.\n\terr = generatecmd.Run(context.Background(), io.Discard, io.Discard, []string{\"-path\", appDir, \"-include-version=false\", \"-include-timestamp=false\", \"-keep-orphaned-files=false\"})\n\tif err == nil {\n\t\tt.Errorf(\"expected generation error, got %v\", err)\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/testwatch/testdata/go.mod.embed",
    "content": "module templ/testproject\n\ngo 1.25.0\n\nrequire github.com/a-h/templ v0.3.847 // indirect\n\nreplace github.com/a-h/templ => {moduleRoot}\n"
  },
  {
    "path": "cmd/templ/generatecmd/testwatch/testdata/go.sum",
    "content": "github.com/a-h/templ v0.3.833 h1:L/KOk/0VvVTBegtE0fp2RJQiBm7/52Zxv5fqlEHiQUU=\ngithub.com/a-h/templ v0.3.833/go.mod h1:cAu4AiZhtJfBjMY0HASlyzvkrtjnHWPeEsyGK2YYmfk=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "cmd/templ/generatecmd/testwatch/testdata/main.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"flag\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/a-h/templ\"\n)\n\ntype GzipResponseWriter struct {\n\tw http.ResponseWriter\n}\n\nfunc (w *GzipResponseWriter) Header() http.Header {\n\treturn w.w.Header()\n}\n\nfunc (w *GzipResponseWriter) Write(b []byte) (int, error) {\n\tvar buf bytes.Buffer\n\tgzw := gzip.NewWriter(&buf)\n\tdefer gzw.Close()\n\n\t_, err := gzw.Write(b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\terr = gzw.Close()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tw.w.Header().Set(\"Content-Length\", strconv.Itoa(buf.Len()))\n\n\treturn w.w.Write(buf.Bytes())\n}\n\nfunc (w *GzipResponseWriter) WriteHeader(statusCode int) {\n\tw.w.WriteHeader(statusCode)\n}\n\nvar flagPort = flag.Int(\"port\", 0, \"Set the HTTP listen port\")\nvar useGzip = flag.Bool(\"gzip\", false, \"Toggle gzip encoding\")\n\nfunc main() {\n\tflag.Parse()\n\n\tif *flagPort == 0 {\n\t\tfmt.Println(\"missing port flag\")\n\t\tos.Exit(1)\n\t}\n\n\tvar count int\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tif useGzip != nil && *useGzip {\n\t\t\tw.Header().Set(\"Content-Encoding\", \"gzip\")\n\t\t\tw = &GzipResponseWriter{w: w}\n\t\t}\n\n\t\tcount++\n\t\tc := Page(count)\n\t\th := templ.Handler(c)\n\t\th.ErrorHandler = func(r *http.Request, err error) http.Handler {\n\t\t\tslog.Error(\"failed to render template\", slog.Any(\"error\", err))\n\t\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\t})\n\t\t}\n\t\th.ServeHTTP(w, r)\n\t})\n\terr := http.ListenAndServe(fmt.Sprintf(\"localhost:%d\", *flagPort), nil)\n\tif err != nil {\n\t\tfmt.Printf(\"Error listening: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/testwatch/testdata/templates.templ",
    "content": "package main\n\nimport \"fmt\"\n\ntempl Page(count int) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<title>templ test page</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>Count</h1>\n\t\t\t<div data-testid=\"count\">{ fmt.Sprintf(\"%d\", count) }</div>\n\t\t\t<div data-testid=\"modification\">Original</div>\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/testwatch/testdata/templates_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"fmt\"\n\nfunc Page(count int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype html><html><head><title>templ test page</title></head><body><h1>Count</h1><div data-testid=\\\"count\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(\"%d\", count))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/generatecmd/testwatch/testdata/templates.templ`, Line: 13, Col: 54}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div><div data-testid=\\\"modification\\\">Original</div></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "cmd/templ/generatecmd/watcher/watch.go",
    "content": "package watcher\n\nimport (\n\t\"context\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/internal/skipdir\"\n\t\"github.com/fsnotify/fsnotify\"\n)\n\nfunc Recursive(\n\tctx context.Context,\n\twatchPattern *regexp.Regexp,\n\tignorePattern *regexp.Regexp,\n\tout chan fsnotify.Event,\n\terrors chan error,\n) (w *RecursiveWatcher, err error) {\n\tfsnw, err := fsnotify.NewWatcher()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tw = &RecursiveWatcher{\n\t\tctx:           ctx,\n\t\tw:             fsnw,\n\t\tWatchPattern:  watchPattern,\n\t\tIgnorePattern: ignorePattern,\n\t\tEvents:        out,\n\t\tErrors:        errors,\n\t\ttimers:        make(map[timerKey]*time.Timer),\n\t\tloopComplete:  sync.WaitGroup{},\n\t}\n\tw.loopComplete.Add(1)\n\tgo func() {\n\t\tdefer w.loopComplete.Done()\n\t\tw.loop()\n\t}()\n\treturn w, nil\n}\n\n// WalkFiles walks the file tree rooted at path, sending a Create event for each\n// file it encounters.\nfunc WalkFiles(ctx context.Context, rootPath string, watchPattern, ignorePattern *regexp.Regexp, out chan fsnotify.Event) (err error) {\n\treturn fs.WalkDir(os.DirFS(rootPath), \".\", func(path string, info os.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tabsPath, err := filepath.Abs(filepath.Join(rootPath, path))\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif info.IsDir() && skipdir.ShouldSkip(absPath) {\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\tif !watchPattern.MatchString(absPath) {\n\t\t\treturn nil\n\t\t}\n\t\tif ignorePattern != nil && ignorePattern.MatchString(absPath) {\n\t\t\treturn nil\n\t\t}\n\t\tout <- fsnotify.Event{\n\t\t\tName: absPath,\n\t\t\tOp:   fsnotify.Create,\n\t\t}\n\t\treturn nil\n\t})\n}\n\ntype RecursiveWatcher struct {\n\tctx           context.Context\n\tw             *fsnotify.Watcher\n\tWatchPattern  *regexp.Regexp\n\tIgnorePattern *regexp.Regexp\n\tEvents        chan fsnotify.Event\n\tErrors        chan error\n\ttimerMu       sync.Mutex\n\ttimers        map[timerKey]*time.Timer\n\tloopComplete  sync.WaitGroup\n}\n\ntype timerKey struct {\n\tname string\n\top   fsnotify.Op\n}\n\nfunc timerKeyFromEvent(event fsnotify.Event) timerKey {\n\treturn timerKey{\n\t\tname: event.Name,\n\t\top:   event.Op,\n\t}\n}\n\nfunc (w *RecursiveWatcher) Close() error {\n\tw.loopComplete.Wait()\n\tfor _, timer := range w.timers {\n\t\ttimer.Stop()\n\t}\n\treturn w.w.Close()\n}\n\nfunc (w *RecursiveWatcher) loop() {\n\tfor {\n\t\tselect {\n\t\tcase <-w.ctx.Done():\n\t\t\treturn\n\t\tcase event, ok := <-w.w.Events:\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif event.Has(fsnotify.Create) {\n\t\t\t\tif err := w.Add(event.Name); err != nil {\n\t\t\t\t\tw.Errors <- err\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Only notify on templ related files.\n\t\t\tif !w.WatchPattern.MatchString(event.Name) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Skip files that match the ignore pattern.\n\t\t\tif w.IgnorePattern != nil && w.IgnorePattern.MatchString(event.Name) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttk := timerKeyFromEvent(event)\n\t\t\tw.timerMu.Lock()\n\t\t\tt, ok := w.timers[tk]\n\t\t\tw.timerMu.Unlock()\n\t\t\tif !ok {\n\t\t\t\tt = time.AfterFunc(100*time.Millisecond, func() {\n\t\t\t\t\tif w.ctx.Err() != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tw.Events <- event\n\t\t\t\t})\n\t\t\t\tw.timerMu.Lock()\n\t\t\t\tw.timers[tk] = t\n\t\t\t\tw.timerMu.Unlock()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tt.Reset(100 * time.Millisecond)\n\t\tcase err, ok := <-w.w.Errors:\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tw.Errors <- err\n\t\t}\n\t}\n}\n\nfunc (w *RecursiveWatcher) Add(dir string) error {\n\treturn filepath.WalkDir(dir, func(dir string, info os.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !info.IsDir() {\n\t\t\treturn nil\n\t\t}\n\t\tif skipdir.ShouldSkip(dir) {\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\treturn w.w.Add(dir)\n\t})\n}\n"
  },
  {
    "path": "cmd/templ/generatecmd/watcher/watch_test.go",
    "content": "package watcher\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/fsnotify/fsnotify\"\n)\n\nfunc TestWatchDebouncesDuplicates(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tevents := make(chan fsnotify.Event, 2)\n\terrors := make(chan error)\n\twatchPattern, err := regexp.Compile(\".*\")\n\tif err != nil {\n\t\tt.Fatal(fmt.Errorf(\"failed to compile watch pattern: %w\", err))\n\t}\n\trw, err := Recursive(ctx, watchPattern, nil, events, errors)\n\tif err != nil {\n\t\tt.Fatal(fmt.Errorf(\"failed to create recursive watcher: %w\", err))\n\t}\n\tgo func() {\n\t\trw.w.Events <- fsnotify.Event{Name: \"test.templ\"}\n\t\trw.w.Events <- fsnotify.Event{Name: \"test.templ\"}\n\t}()\n\tcount := 0\n\texp := time.After(300 * time.Millisecond)\n\tfor {\n\t\tselect {\n\t\tcase <-rw.Events:\n\t\t\tcount++\n\t\tcase <-exp:\n\t\t\tif count != 1 {\n\t\t\t\tt.Errorf(\"expected 1 event, got %d\", count)\n\t\t\t}\n\t\t\tcancel()\n\t\t\tif err := rw.Close(); err != nil {\n\t\t\t\tt.Errorf(\"unexpected error closing watcher: %v\", err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc TestWatchDoesNotDebounceDifferentEvents(t *testing.T) {\n\ttests := []struct {\n\t\tevent1 fsnotify.Event\n\t\tevent2 fsnotify.Event\n\t}{\n\t\t// Different files\n\t\t{fsnotify.Event{Name: \"test.templ\"}, fsnotify.Event{Name: \"test2.templ\"}},\n\t\t// Different operations\n\t\t{\n\t\t\tfsnotify.Event{Name: \"test.templ\", Op: fsnotify.Create},\n\t\t\tfsnotify.Event{Name: \"test.templ\", Op: fsnotify.Write},\n\t\t},\n\t\t// Different operations and files\n\t\t{\n\t\t\tfsnotify.Event{Name: \"test.templ\", Op: fsnotify.Create},\n\t\t\tfsnotify.Event{Name: \"test2.templ\", Op: fsnotify.Write},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tctx, cancel := context.WithCancel(context.Background())\n\t\tevents := make(chan fsnotify.Event, 2)\n\t\terrors := make(chan error)\n\t\twatchPattern, err := regexp.Compile(\".*\")\n\t\tif err != nil {\n\t\t\tt.Fatal(fmt.Errorf(\"failed to compile watch pattern: %w\", err))\n\t\t}\n\t\trw, err := Recursive(ctx, watchPattern, nil, events, errors)\n\t\tif err != nil {\n\t\t\tt.Fatal(fmt.Errorf(\"failed to create recursive watcher: %w\", err))\n\t\t}\n\t\tgo func() {\n\t\t\trw.w.Events <- test.event1\n\t\t\trw.w.Events <- test.event2\n\t\t}()\n\t\tcount := 0\n\t\texp := time.After(300 * time.Millisecond)\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-rw.Events:\n\t\t\t\tcount++\n\t\t\tcase <-exp:\n\t\t\t\tif count != 2 {\n\t\t\t\t\tt.Errorf(\"expected 2 event, got %d\", count)\n\t\t\t\t}\n\t\t\t\tcancel()\n\t\t\t\tif err := rw.Close(); err != nil {\n\t\t\t\t\tt.Errorf(\"unexpected error closing watcher: %v\", err)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestWatchDoesNotDebounceSeparateEvents(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tevents := make(chan fsnotify.Event, 2)\n\terrors := make(chan error)\n\twatchPattern, err := regexp.Compile(\".*\")\n\tif err != nil {\n\t\tt.Fatal(fmt.Errorf(\"failed to compile watch pattern: %w\", err))\n\t}\n\trw, err := Recursive(ctx, watchPattern, nil, events, errors)\n\tif err != nil {\n\t\tt.Fatal(fmt.Errorf(\"failed to create recursive watcher: %w\", err))\n\t}\n\tgo func() {\n\t\trw.w.Events <- fsnotify.Event{Name: \"test.templ\"}\n\t\t<-time.After(200 * time.Millisecond)\n\t\trw.w.Events <- fsnotify.Event{Name: \"test.templ\"}\n\t}()\n\tcount := 0\n\texp := time.After(500 * time.Millisecond)\n\tfor {\n\t\tselect {\n\t\tcase <-rw.Events:\n\t\t\tcount++\n\t\tcase <-exp:\n\t\t\tif count != 2 {\n\t\t\t\tt.Errorf(\"expected 2 event, got %d\", count)\n\t\t\t}\n\t\t\tcancel()\n\t\t\tif err := rw.Close(); err != nil {\n\t\t\t\tt.Errorf(\"unexpected error closing watcher: %v\", err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc TestWatchIgnoresFilesMatchingIgnorePattern(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tevents := make(chan fsnotify.Event, 2)\n\terrors := make(chan error)\n\twatchPattern, err := regexp.Compile(\".*\")\n\tif err != nil {\n\t\tt.Fatal(fmt.Errorf(\"failed to compile watch pattern: %w\", err))\n\t}\n\tignorePattern, err := regexp.Compile(`ignore\\.templ$`)\n\tif err != nil {\n\t\tt.Fatal(fmt.Errorf(\"failed to compile ignore pattern: %w\", err))\n\t}\n\n\trw, err := Recursive(ctx, watchPattern, ignorePattern, events, errors)\n\tif err != nil {\n\t\tt.Fatal(fmt.Errorf(\"failed to create recursive watcher: %w\", err))\n\t}\n\n\tgo func() {\n\t\t// This should be ignored\n\t\trw.w.Events <- fsnotify.Event{Name: \"file.ignore.templ\"}\n\t\t// This should pass\n\t\trw.w.Events <- fsnotify.Event{Name: \"file.keep.templ\"}\n\t}()\n\n\tcount := 0\n\texp := time.After(300 * time.Millisecond)\n\tfor {\n\t\tselect {\n\t\tcase <-rw.Events:\n\t\t\tcount++\n\t\tcase <-exp:\n\t\t\tif count != 1 {\n\t\t\t\tt.Errorf(\"expected 1 event, got %d\", count)\n\t\t\t}\n\t\t\tcancel()\n\t\t\tif err := rw.Close(); err != nil {\n\t\t\t\tt.Errorf(\"unexpected error closing watcher: %v\", err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc TestIgnorePatternTakesPrecedenceOverWatchPattern(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tevents := make(chan fsnotify.Event, 2)\n\terrors := make(chan error)\n\twatchPattern := regexp.MustCompile(`.*\\.templ$`)\n\tignorePattern := regexp.MustCompile(`.*\\.ignore\\.templ$`)\n\n\trw, err := Recursive(ctx, watchPattern, ignorePattern, events, errors)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tgo func() {\n\t\trw.w.Events <- fsnotify.Event{Name: \"file.ignore.templ\"}\n\t}()\n\n\texp := time.After(300 * time.Millisecond)\n\tselect {\n\tcase <-rw.Events:\n\t\tt.Errorf(\"expected no events because ignore should win\")\n\tcase <-exp:\n\t\tcancel()\n\t\t_ = rw.Close()\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/infocmd/main.go",
    "content": "package infocmd\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/cmd/templ/lspcmd/pls\"\n)\n\ntype Arguments struct {\n\tJSON bool `flag:\"json\" help:\"Output info as JSON.\"`\n}\n\ntype Info struct {\n\tOS struct {\n\t\tGOOS   string `json:\"goos\"`\n\t\tGOARCH string `json:\"goarch\"`\n\t} `json:\"os\"`\n\tGo       ToolInfo `json:\"go\"`\n\tGopls    ToolInfo `json:\"gopls\"`\n\tTempl    ToolInfo `json:\"templ\"`\n\tPrettier ToolInfo `json:\"prettier\"`\n}\n\ntype ToolInfo struct {\n\tLocation string     `json:\"location\"`\n\tVersion  string     `json:\"version\"`\n\tLevel    slog.Level `json:\"level\"`\n\tMessage  string     `json:\"message,omitempty\"`\n}\n\nfunc getGoInfo() (d ToolInfo) {\n\td.Level = slog.LevelError\n\n\tvar err error\n\td.Location, err = exec.LookPath(\"go\")\n\tif err != nil {\n\t\td.Message = fmt.Sprintf(\"failed to find go: %v\", err)\n\t\treturn\n\t}\n\tcmd := exec.Command(d.Location, \"version\")\n\tv, err := cmd.Output()\n\tif err != nil {\n\t\td.Message = fmt.Sprintf(\"failed to get go version, check that Go is installed: %v\", err)\n\t\treturn\n\t}\n\td.Version = strings.TrimSpace(string(v))\n\td.Level = slog.LevelInfo\n\treturn\n}\n\nfunc getGoplsInfo() (d ToolInfo) {\n\td.Level = slog.LevelError\n\n\tvar err error\n\td.Location, err = pls.FindGopls()\n\tif err != nil {\n\t\td.Message = fmt.Sprintf(\"failed to find gopls: %v\", err)\n\t\treturn\n\t}\n\tcmd := exec.Command(d.Location, \"version\")\n\tv, err := cmd.Output()\n\tif err != nil {\n\t\td.Message = fmt.Sprintf(\"failed to get gopls version: %v\", err)\n\t\treturn\n\t}\n\td.Version = strings.TrimSpace(string(v))\n\td.Level = slog.LevelInfo\n\treturn\n}\n\nfunc getTemplInfo() (d ToolInfo) {\n\td.Level = slog.LevelError\n\n\tvar err error\n\td.Location, err = findTempl()\n\tif err != nil {\n\t\td.Message = err.Error()\n\t\treturn\n\t}\n\tcmd := exec.Command(d.Location, \"version\")\n\tv, err := cmd.Output()\n\tif err != nil {\n\t\td.Message = fmt.Sprintf(\"failed to get templ version: %v\", err)\n\t\treturn\n\t}\n\td.Version = strings.TrimSpace(string(v))\n\tif d.Version != templ.Version() {\n\t\td.Message = fmt.Sprintf(\"version mismatch - you're running %q at the command line, but the version in the path is %q\", templ.Version(), d.Version)\n\t\treturn\n\t}\n\td.Level = slog.LevelInfo\n\treturn\n}\n\nfunc findTempl() (location string, err error) {\n\texecutableName := \"templ\"\n\tif runtime.GOOS == \"windows\" {\n\t\texecutableName = \"templ.exe\"\n\t}\n\texecutableName, err = exec.LookPath(executableName)\n\tif err == nil {\n\t\t// Found on the path.\n\t\treturn executableName, nil\n\t}\n\n\t// Unexpected error.\n\tif !errors.Is(err, exec.ErrNotFound) {\n\t\treturn \"\", fmt.Errorf(\"unexpected error looking for templ: %w\", err)\n\t}\n\n\treturn \"\", fmt.Errorf(\"templ is not in the path (%q). You can install templ with `go install github.com/a-h/templ/cmd/templ@latest`\", os.Getenv(\"PATH\"))\n}\n\nfunc getPrettierInfo() (d ToolInfo) {\n\td.Level = slog.LevelWarn\n\n\tvar err error\n\td.Location, err = exec.LookPath(\"prettier\")\n\tif err != nil {\n\t\td.Message = fmt.Sprintf(\"failed to find prettier: %v\", err)\n\t\treturn\n\t}\n\tcmd := exec.Command(d.Location, \"--version\")\n\tv, err := cmd.Output()\n\tif err != nil {\n\t\td.Message = fmt.Sprintf(\"failed to get prettier version: %v\", err)\n\t\treturn\n\t}\n\td.Version = strings.TrimSpace(string(v))\n\td.Level = slog.LevelInfo\n\treturn\n}\n\nfunc getInfo() (d Info) {\n\td.OS.GOOS = runtime.GOOS\n\td.OS.GOARCH = runtime.GOARCH\n\n\tvar wg sync.WaitGroup\n\twg.Add(4)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\td.Go = getGoInfo()\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\td.Gopls = getGoplsInfo()\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\td.Templ = getTemplInfo()\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\td.Prettier = getPrettierInfo()\n\t}()\n\twg.Wait()\n\treturn\n}\n\nfunc Run(ctx context.Context, log *slog.Logger, stdout io.Writer, args Arguments) (err error) {\n\tinfo := getInfo()\n\tif args.JSON {\n\t\tenc := json.NewEncoder(stdout)\n\t\tenc.SetIndent(\"\", \"  \")\n\t\treturn enc.Encode(info)\n\t}\n\tlog.Info(\"os\", slog.String(\"goos\", info.OS.GOOS), slog.String(\"goarch\", info.OS.GOARCH))\n\tlogInfo(ctx, log, \"go\", info.Go)\n\tlogInfo(ctx, log, \"gopls\", info.Gopls)\n\tlogInfo(ctx, log, \"templ\", info.Templ)\n\tlogInfo(ctx, log, \"prettier\", info.Prettier)\n\treturn nil\n}\n\nfunc logInfo(ctx context.Context, log *slog.Logger, name string, ti ToolInfo) {\n\targs := []any{\n\t\tslog.String(\"location\", ti.Location),\n\t\tslog.String(\"version\", ti.Version),\n\t}\n\tif ti.Message != \"\" {\n\t\targs = append(args, slog.String(\"message\", ti.Message))\n\t}\n\tlog.Log(ctx, ti.Level, name, args...)\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/httpdebug/handler.go",
    "content": "package httpdebug\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/cmd/templ/lspcmd/proxy\"\n\t\"github.com/a-h/templ/cmd/templ/visualize\"\n)\n\nvar log *slog.Logger\n\nfunc NewHandler(l *slog.Logger, s *proxy.Server) http.Handler {\n\tm := http.NewServeMux()\n\tlog = l\n\tm.HandleFunc(\"/templ\", func(w http.ResponseWriter, r *http.Request) {\n\t\turi := r.URL.Query().Get(\"uri\")\n\t\tc, ok := s.TemplSource.Get(uri)\n\t\tif !ok {\n\t\t\tError(w, \"uri not found\", http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tString(w, c.String())\n\t})\n\tm.HandleFunc(\"/sourcemap\", func(w http.ResponseWriter, r *http.Request) {\n\t\turi := r.URL.Query().Get(\"uri\")\n\t\tsm, ok := s.SourceMapCache.Get(uri)\n\t\tif !ok {\n\t\t\tError(w, \"uri not found\", http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tJSON(w, sm.SourceLinesToTarget)\n\t})\n\tm.HandleFunc(\"/go\", func(w http.ResponseWriter, r *http.Request) {\n\t\turi := r.URL.Query().Get(\"uri\")\n\t\tc, ok := s.GoSource[uri]\n\t\tif !ok {\n\t\t\tError(w, \"uri not found\", http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tString(w, c)\n\t})\n\tm.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\turi := r.URL.Query().Get(\"uri\")\n\t\tif uri == \"\" {\n\t\t\t// List all URIs.\n\t\t\tif err := list(s.TemplSource.URIs()).Render(r.Context(), w); err != nil {\n\t\t\t\tError(w, \"failed to list URIs\", http.StatusInternalServerError)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\t// Assume we've got a URI.\n\t\ttemplSource, ok := s.TemplSource.Get(uri)\n\t\tif !ok {\n\t\t\tif !ok {\n\t\t\t\tError(w, \"uri not found in document contents\", http.StatusNotFound)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tgoSource, ok := s.GoSource[uri]\n\t\tif !ok {\n\t\t\tif !ok {\n\t\t\t\tError(w, \"uri not found in document contents\", http.StatusNotFound)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tsm, ok := s.SourceMapCache.Get(uri)\n\t\tif !ok {\n\t\t\tError(w, \"uri not found\", http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tif err := visualize.HTML(uri, templSource.String(), goSource, sm).Render(r.Context(), w); err != nil {\n\t\t\tError(w, \"failed to visualize HTML\", http.StatusInternalServerError)\n\t\t}\n\t})\n\treturn m\n}\n\nfunc getMapURL(uri string) templ.SafeURL {\n\treturn withQuery(\"/\", uri)\n}\n\nfunc getSourceMapURL(uri string) templ.SafeURL {\n\treturn withQuery(\"/sourcemap\", uri)\n}\n\nfunc getTemplURL(uri string) templ.SafeURL {\n\treturn withQuery(\"/templ\", uri)\n}\n\nfunc getGoURL(uri string) templ.SafeURL {\n\treturn withQuery(\"/go\", uri)\n}\n\nfunc withQuery(path, uri string) templ.SafeURL {\n\tq := make(url.Values)\n\tq.Set(\"uri\", uri)\n\tu := &url.URL{\n\t\tPath:     path,\n\t\tRawPath:  path,\n\t\tRawQuery: q.Encode(),\n\t}\n\treturn templ.SafeURL(u.String())\n}\n\nfunc JSON(w http.ResponseWriter, v any) {\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tenc := json.NewEncoder(w)\n\tenc.SetIndent(\"\", \"  \")\n\tif err := enc.Encode(v); err != nil {\n\t\tlog.Error(\"failed to write JSON response\", slog.Any(\"error\", err))\n\t}\n}\n\nfunc String(w http.ResponseWriter, s string) {\n\tif _, err := io.WriteString(w, s); err != nil {\n\t\tlog.Error(\"failed to write string response\", slog.Any(\"error\", err))\n\t}\n}\n\nfunc Error(w http.ResponseWriter, msg string, status int) {\n\tw.WriteHeader(status)\n\tif _, err := io.WriteString(w, msg); err != nil {\n\t\tlog.Error(\"failed to write error response\", slog.Any(\"error\", err))\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/httpdebug/list.templ",
    "content": "package httpdebug\n\ntempl list(uris []string) {\n\t<table>\n\t\t<tr>\n\t\t\t<th>File</th>\n\t\t\t<th></th>\n\t\t\t<th></th>\n\t\t\t<th></th>\n\t\t\t<th></th>\n\t\t</tr>\n\t\tfor _, uri := range uris {\n\t\t\t<tr>\n\t\t\t\t<td>{ uri }</td>\n\t\t\t\t<td><a href={ getMapURL(uri) }>Mapping</a></td>\n\t\t\t\t<td><a href={ getSourceMapURL(uri) }>Source Map</a></td>\n\t\t\t\t<td><a href={ getTemplURL(uri) }>Templ</a></td>\n\t\t\t\t<td><a href={ getGoURL(uri) }>Go</a></td>\n\t\t\t</tr>\n\t\t}\n\t</table>\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/httpdebug/list_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage httpdebug\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc list(uris []string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<table><tr><th>File</th><th></th><th></th><th></th><th></th></tr>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor _, uri := range uris {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<tr><td>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(uri)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/lspcmd/httpdebug/list.templ`, Line: 14, Col: 13}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</td><td><a href=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var3 templ.SafeURL\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(getMapURL(uri))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/lspcmd/httpdebug/list.templ`, Line: 15, Col: 32}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\">Mapping</a></td><td><a href=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var4 templ.SafeURL\n\t\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(getSourceMapURL(uri))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/lspcmd/httpdebug/list.templ`, Line: 16, Col: 38}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"\\\">Source Map</a></td><td><a href=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var5 templ.SafeURL\n\t\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinURLErrs(getTemplURL(uri))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/lspcmd/httpdebug/list.templ`, Line: 17, Col: 34}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"\\\">Templ</a></td><td><a href=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var6 templ.SafeURL\n\t\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinURLErrs(getGoURL(uri))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/lspcmd/httpdebug/list.templ`, Line: 18, Col: 31}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\">Go</a></td></tr>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"</table>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "cmd/templ/lspcmd/lsp_test.go",
    "content": "package lspcmd\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"github.com/a-h/templ/cmd/templ/generatecmd/modcheck\"\n\t\"github.com/a-h/templ/cmd/templ/lspcmd/lspdiff\"\n\t\"github.com/a-h/templ/cmd/templ/testproject\"\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n\t\"github.com/a-h/templ/lsp/protocol\"\n\t\"github.com/a-h/templ/lsp/uri\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestCompletion(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\ttestOutput := bytes.NewBuffer(nil)\n\tlog := slog.New(slog.NewJSONHandler(testOutput, nil))\n\tdefer func() {\n\t\tif t.Failed() {\n\t\t\tfmt.Println(testOutput.String())\n\t\t}\n\t}()\n\n\tctx, appDir, _, server, teardown, err := Setup(ctx, log)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\tdefer cancel()\n\n\ttemplFile, err := os.ReadFile(appDir + \"/templates.templ\")\n\tif err != nil {\n\t\tt.Errorf(\"failed to read file %q: %v\", appDir+\"/templates.templ\", err)\n\t\treturn\n\t}\n\terr = server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{\n\t\tTextDocument: protocol.TextDocumentItem{\n\t\t\tURI:        uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\tLanguageID: \"templ\",\n\t\t\tVersion:    1,\n\t\t\tText:       string(templFile),\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Errorf(\"failed to register open file: %v\", err)\n\t\treturn\n\t}\n\tlog.Info(\"Calling completion\")\n\n\tglobalSnippetsLen := 1\n\n\t// Edit the file.\n\t// Replace:\n\t// <div data-testid=\"count\">{ fmt.Sprintf(\"%d\", count) }</div>\n\t// With various tests:\n\t// <div data-testid=\"count\">{ f\n\ttests := []struct {\n\t\tline        int\n\t\treplacement string\n\t\tcursor      string\n\t\tassert      func(t *testing.T, cl *protocol.CompletionList) (msg string, ok bool)\n\t}{\n\t\t{\n\t\t\tline:        13,\n\t\t\treplacement: ` <div data-testid=\"count\">{  `,\n\t\t\tcursor:      `                            ^`,\n\t\t\tassert: func(t *testing.T, actual *protocol.CompletionList) (msg string, ok bool) {\n\t\t\t\tif actual == nil || len(actual.Items) == globalSnippetsLen {\n\t\t\t\t\treturn \"expected completion list not to be empty or just the default\", false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tline:        13,\n\t\t\treplacement: ` <div data-testid=\"count\">{ fmt.`,\n\t\t\tcursor:      `                               ^`,\n\t\t\tassert: func(t *testing.T, actual *protocol.CompletionList) (msg string, ok bool) {\n\t\t\t\tif !lspdiff.CompletionListContainsText(actual, \"fmt.Sprintf\") {\n\t\t\t\t\treturn fmt.Sprintf(\"expected fmt.Sprintf to be in the completion list, but got %#v\", actual), false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tline:        13,\n\t\t\treplacement: ` <div data-testid=\"count\">{ fmt.Sprintf(\"%d\",`,\n\t\t\tcursor:      `                                            ^`,\n\t\t\tassert: func(t *testing.T, actual *protocol.CompletionList) (msg string, ok bool) {\n\t\t\t\tif actual != nil && len(actual.Items) != globalSnippetsLen {\n\t\t\t\t\treturn \"expected completion list to be empty\", false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t}\n\n\tfor i, test := range tests {\n\t\tt.Run(fmt.Sprintf(\"test-%d\", i), func(t *testing.T) {\n\t\t\t// Edit the file.\n\t\t\tupdated := testproject.MustReplaceLine(string(templFile), test.line, test.replacement)\n\t\t\terr = server.DidChange(ctx, &protocol.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: protocol.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: protocol.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\t\t\t},\n\t\t\t\t\tVersion: int32(i + 2),\n\t\t\t\t},\n\t\t\t\tContentChanges: []protocol.TextDocumentContentChangeEvent{\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: nil,\n\t\t\t\t\t\tText:  updated,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to change file: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Give CI/CD pipeline executors some time because they're often quite slow.\n\t\t\tvar ok bool\n\t\t\tvar msg string\n\t\t\tfor range 3 {\n\t\t\t\tactual, err := server.Completion(ctx, &protocol.CompletionParams{\n\t\t\t\t\tContext: &protocol.CompletionContext{\n\t\t\t\t\t\tTriggerCharacter: \".\",\n\t\t\t\t\t\tTriggerKind:      protocol.CompletionTriggerKindTriggerCharacter,\n\t\t\t\t\t},\n\t\t\t\t\tTextDocumentPositionParams: protocol.TextDocumentPositionParams{\n\t\t\t\t\t\tTextDocument: protocol.TextDocumentIdentifier{\n\t\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// Positions are zero indexed.\n\t\t\t\t\t\tPosition: protocol.Position{\n\t\t\t\t\t\t\tLine:      uint32(test.line - 1),\n\t\t\t\t\t\t\tCharacter: uint32(len(test.cursor) - 1),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"failed to get completion: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmsg, ok = test.assert(t, actual)\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttime.Sleep(time.Millisecond * 500)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Error(msg)\n\t\t\t}\n\t\t})\n\t}\n\tlog.Info(\"Completed test\")\n}\n\nfunc TestHover(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\ttestOutput := bytes.NewBuffer(nil)\n\tlog := slog.New(slog.NewJSONHandler(testOutput, nil))\n\tdefer func() {\n\t\tif t.Failed() {\n\t\t\tfmt.Println(testOutput.String())\n\t\t}\n\t}()\n\n\tctx, appDir, _, server, teardown, err := Setup(ctx, log)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\tdefer cancel()\n\n\ttemplFile, err := os.ReadFile(appDir + \"/templates.templ\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read file %q: %v\", appDir+\"/templates.templ\", err)\n\t}\n\terr = server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{\n\t\tTextDocument: protocol.TextDocumentItem{\n\t\t\tURI:        uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\tLanguageID: \"templ\",\n\t\t\tVersion:    1,\n\t\t\tText:       string(templFile),\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Errorf(\"failed to register open file: %v\", err)\n\t\treturn\n\t}\n\tlog.Info(\"Calling hover\")\n\n\t// Edit the file.\n\t// Replace:\n\t// <div data-testid=\"count\">{ fmt.Sprintf(\"%d\", count) }</div>\n\t// With various tests:\n\t// <div data-testid=\"count\">{ f\n\ttests := []struct {\n\t\tline        int\n\t\treplacement string\n\t\tcursor      string\n\t\tassert      func(t *testing.T, hr *protocol.Hover) (msg string, ok bool)\n\t}{\n\t\t{\n\t\t\tline:        13,\n\t\t\treplacement: `\t\t\t<div data-testid=\"count\">{ fmt.Sprintf(\"%d\", count) }</div>`,\n\t\t\tcursor:      `                                 ^`,\n\t\t\tassert: func(t *testing.T, actual *protocol.Hover) (msg string, ok bool) {\n\t\t\t\tif actual.Contents.Kind != \"markdown\" {\n\t\t\t\t\treturn fmt.Sprintf(\"expected hover kind to be markdown, got %q\", actual.Contents.Kind), false\n\t\t\t\t}\n\t\t\t\tif !strings.Contains(actual.Contents.Value, \"```go\\npackage fmt\\n```\") {\n\t\t\t\t\treturn fmt.Sprintf(\"expected hover to contain package fmt, got %q\", actual.Contents.Value), false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tline:        13,\n\t\t\treplacement: `\t\t\t<div data-testid=\"count\">{ fmt.Sprintf(\"%d\", count) }</div>`,\n\t\t\tcursor:      `                                     ^`,\n\t\t\tassert: func(t *testing.T, actual *protocol.Hover) (msg string, ok bool) {\n\t\t\t\tif actual == nil {\n\t\t\t\t\treturn \"expected hover to be non-nil\", false\n\t\t\t\t}\n\t\t\t\tif actual.Contents.Kind != \"markdown\" {\n\t\t\t\t\treturn fmt.Sprintf(\"expected hover kind to be markdown, got %q\", actual.Contents.Kind), false\n\t\t\t\t}\n\t\t\t\tif !strings.Contains(actual.Contents.Value, \"```go\\nfunc fmt.Sprintf(format string, a ...any) string\\n```\") {\n\t\t\t\t\treturn fmt.Sprintf(\"expected hover to contain fmt.Sprintf signature, got %q\", actual.Contents.Value), false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tline:        19,\n\t\t\treplacement: `var nihao = \"你好\"`,\n\t\t\tcursor:      `             ^`,\n\t\t\tassert: func(t *testing.T, actual *protocol.Hover) (msg string, ok bool) {\n\t\t\t\t// There's nothing to hover, just want to make sure it doesn't panic.\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t}\n\n\tfor i, test := range tests {\n\t\tt.Run(fmt.Sprintf(\"test-%d\", i), func(t *testing.T) {\n\t\t\t// Put the file back to the initial point.\n\t\t\terr = server.DidChange(ctx, &protocol.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: protocol.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: protocol.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\t\t\t},\n\t\t\t\t\tVersion: int32(i + 2),\n\t\t\t\t},\n\t\t\t\tContentChanges: []protocol.TextDocumentContentChangeEvent{\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: nil,\n\t\t\t\t\t\tText:  string(templFile),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to change file: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Give CI/CD pipeline executors some time because they're often quite slow.\n\t\t\tvar ok bool\n\t\t\tvar msg string\n\t\t\tfor range 3 {\n\t\t\t\tlspCharIndex, err := runeIndexToUTF8ByteIndex(test.replacement, len(test.cursor)-1)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t\tactual, err := server.Hover(ctx, &protocol.HoverParams{\n\t\t\t\t\tTextDocumentPositionParams: protocol.TextDocumentPositionParams{\n\t\t\t\t\t\tTextDocument: protocol.TextDocumentIdentifier{\n\t\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// Positions are zero indexed.\n\t\t\t\t\t\tPosition: protocol.Position{\n\t\t\t\t\t\t\tLine:      uint32(test.line - 1),\n\t\t\t\t\t\t\tCharacter: lspCharIndex,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"failed to hover: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmsg, ok = test.assert(t, actual)\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttime.Sleep(time.Millisecond * 500)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Error(msg)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestReferences(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\n\ttestOutput := bytes.NewBuffer(nil)\n\tlog := slog.New(slog.NewJSONHandler(testOutput, nil))\n\tdefer func() {\n\t\tif t.Failed() {\n\t\t\tfmt.Println(testOutput.String())\n\t\t}\n\t}()\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tctx, appDir, _, server, teardown, err := Setup(ctx, log)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t\treturn\n\t}\n\tdefer teardown(t)\n\tdefer cancel()\n\n\tlog.Info(\"Calling References\")\n\n\ttests := []struct {\n\t\tline      int\n\t\tcharacter int\n\t\tfilename  string\n\t\tassert    func(t *testing.T, l []protocol.Location) (msg string, ok bool)\n\t}{\n\t\t{\n\t\t\t// this is the definition of the templ function in the templates.templ file.\n\t\t\tline:      5,\n\t\t\tcharacter: 9,\n\t\t\tfilename:  \"/templates.templ\",\n\t\t\tassert: func(t *testing.T, actual []protocol.Location) (msg string, ok bool) {\n\t\t\t\texpectedReference := []protocol.Location{\n\t\t\t\t\t{\n\t\t\t\t\t\t// This is the usage of the templ function in the main.go file.\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/main.go\"),\n\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\tStart: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(24),\n\t\t\t\t\t\t\t\tCharacter: uint32(7),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(24),\n\t\t\t\t\t\t\t\tCharacter: uint32(11),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tif diff := lspdiff.References(expectedReference, actual); diff != \"\" {\n\t\t\t\t\treturn fmt.Sprintf(\"Expected: %+v\\nActual: %+v\", expectedReference, actual), false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t// this is the definition of the struct in the templates.templ file.\n\t\t\tline:      21,\n\t\t\tcharacter: 9,\n\t\t\tfilename:  \"/templates.templ\",\n\t\t\tassert: func(t *testing.T, actual []protocol.Location) (msg string, ok bool) {\n\t\t\t\texpectedReference := []protocol.Location{\n\t\t\t\t\t{\n\t\t\t\t\t\t// This is the usage of the struct in the templates.templ file.\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\tStart: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(24),\n\t\t\t\t\t\t\t\tCharacter: uint32(8),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(24),\n\t\t\t\t\t\t\t\tCharacter: uint32(14),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tif diff := lspdiff.References(expectedReference, actual); diff != \"\" {\n\t\t\t\t\treturn fmt.Sprintf(\"Expected: %+v\\nActual: %+v\", expectedReference, actual), false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t// this test is for inclusions from a remote file that has not been explicitly called with didOpen\n\t\t\tline:      3,\n\t\t\tcharacter: 9,\n\t\t\tfilename:  \"/remotechild.templ\",\n\t\t\tassert: func(t *testing.T, actual []protocol.Location) (msg string, ok bool) {\n\t\t\t\texpectedReference := []protocol.Location{\n\t\t\t\t\t{\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/remoteparent.templ\"),\n\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\tStart: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(3),\n\t\t\t\t\t\t\t\tCharacter: uint32(2),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(3),\n\t\t\t\t\t\t\t\tCharacter: uint32(8),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/remoteparent.templ\"),\n\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\tStart: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(7),\n\t\t\t\t\t\t\t\tCharacter: uint32(2),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: protocol.Position{\n\t\t\t\t\t\t\t\tLine:      uint32(7),\n\t\t\t\t\t\t\t\tCharacter: uint32(8),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tif diff := lspdiff.References(expectedReference, actual); diff != \"\" {\n\t\t\t\t\treturn fmt.Sprintf(\"Expected: %+v\\nActual: %+v\", expectedReference, actual), false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t}\n\n\tfor i, test := range tests {\n\t\tt.Run(fmt.Sprintf(\"test-%d\", i), func(t *testing.T) {\n\t\t\t// Give CI/CD pipeline executors some time because they're often quite slow.\n\t\t\tvar ok bool\n\t\t\tvar msg string\n\t\t\tfor range 3 {\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tactual, err := server.References(ctx, &protocol.ReferenceParams{\n\t\t\t\t\tTextDocumentPositionParams: protocol.TextDocumentPositionParams{\n\t\t\t\t\t\tTextDocument: protocol.TextDocumentIdentifier{\n\t\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + test.filename),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// Positions are zero indexed.\n\t\t\t\t\t\tPosition: protocol.Position{\n\t\t\t\t\t\t\tLine:      uint32(test.line - 1),\n\t\t\t\t\t\t\tCharacter: uint32(test.character - 1),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"failed to get references: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmsg, ok = test.assert(t, actual)\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttime.Sleep(time.Millisecond * 500)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Error(msg)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCodeAction(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\ttestOutput := bytes.NewBuffer(nil)\n\tlog := slog.New(slog.NewJSONHandler(testOutput, nil))\n\tdefer func() {\n\t\tif t.Failed() {\n\t\t\tfmt.Println(testOutput.String())\n\t\t}\n\t}()\n\n\tctx, appDir, _, server, teardown, err := Setup(ctx, log)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\tdefer cancel()\n\n\ttemplFile, err := os.ReadFile(appDir + \"/templates.templ\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read file %q: %v\", appDir+\"/templates.templ\", err)\n\t}\n\terr = server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{\n\t\tTextDocument: protocol.TextDocumentItem{\n\t\t\tURI:        uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\tLanguageID: \"templ\",\n\t\t\tVersion:    1,\n\t\t\tText:       string(templFile),\n\t\t},\n\t})\n\tif err != nil {\n\t\tt.Errorf(\"failed to register open file: %v\", err)\n\t\treturn\n\t}\n\tlog.Info(\"Calling codeAction\")\n\n\ttests := []struct {\n\t\tline        int\n\t\treplacement string\n\t\tcursor      string\n\t\tassert      func(t *testing.T, hr []protocol.CodeAction) (msg string, ok bool)\n\t}{\n\t\t{\n\t\t\tline:        25,\n\t\t\treplacement: `var s = Struct{}`,\n\t\t\tcursor:      `              ^`,\n\t\t\tassert: func(t *testing.T, actual []protocol.CodeAction) (msg string, ok bool) {\n\t\t\t\tvar expected []protocol.CodeAction\n\t\t\t\t// To support code actions, update cmd/templ/lspcmd/proxy/server.go and add the\n\t\t\t\t// Title (e.g. Organize Imports, or Fill Struct) to the supportedCodeActions map.\n\n\t\t\t\t// Some Code Actions are simple edits, so all that is needed is for the server\n\t\t\t\t// to remap the source code positions.\n\n\t\t\t\t// However, other Code Actions are commands, where the arguments must be rewritten\n\t\t\t\t// and will need to be handled individually.\n\t\t\t\tif diff := lspdiff.CodeAction(expected, actual); diff != \"\" {\n\t\t\t\t\treturn fmt.Sprintf(\"unexpected codeAction: %v\", diff), false\n\t\t\t\t}\n\t\t\t\treturn \"\", true\n\t\t\t},\n\t\t},\n\t}\n\n\tfor i, test := range tests {\n\t\tt.Run(fmt.Sprintf(\"test-%d\", i), func(t *testing.T) {\n\t\t\t// Put the file back to the initial point.\n\t\t\terr = server.DidChange(ctx, &protocol.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: protocol.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: protocol.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\t\t\t},\n\t\t\t\t\tVersion: int32(i + 2),\n\t\t\t\t},\n\t\t\t\tContentChanges: []protocol.TextDocumentContentChangeEvent{\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: nil,\n\t\t\t\t\t\tText:  string(templFile),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to change file: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Give CI/CD pipeline executors some time because they're often quite slow.\n\t\t\tvar ok bool\n\t\t\tvar msg string\n\t\t\tfor range 3 {\n\t\t\t\tlspCharIndex, err := runeIndexToUTF8ByteIndex(test.replacement, len(test.cursor)-1)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t\tactual, err := server.CodeAction(ctx, &protocol.CodeActionParams{\n\t\t\t\t\tTextDocument: protocol.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: uri.URI(\"file://\" + appDir + \"/templates.templ\"),\n\t\t\t\t\t},\n\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\tStart: protocol.Position{\n\t\t\t\t\t\t\tLine:      uint32(test.line - 1),\n\t\t\t\t\t\t\tCharacter: lspCharIndex,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: protocol.Position{\n\t\t\t\t\t\t\tLine:      uint32(test.line - 1),\n\t\t\t\t\t\t\tCharacter: lspCharIndex + 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"failed code action: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tmsg, ok = test.assert(t, actual)\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttime.Sleep(time.Millisecond * 500)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Error(msg)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDocumentSymbol(t *testing.T) {\n\tif testing.Short() {\n\t\treturn\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\ttestOutput := bytes.NewBuffer(nil)\n\tlog := slog.New(slog.NewJSONHandler(testOutput, nil))\n\tdefer func() {\n\t\tif t.Failed() {\n\t\t\tfmt.Println(testOutput.String())\n\t\t}\n\t}()\n\n\tctx, appDir, _, server, teardown, err := Setup(ctx, log)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to setup test: %v\", err)\n\t}\n\tdefer teardown(t)\n\tdefer cancel()\n\n\ttests := []struct {\n\t\turi    string\n\t\texpect []protocol.SymbolInformationOrDocumentSymbol\n\t}{\n\t\t{\n\t\t\turi: \"file://\" + appDir + \"/templates.templ\",\n\t\t\texpect: []protocol.SymbolInformationOrDocumentSymbol{\n\t\t\t\t{\n\t\t\t\t\tSymbolInformation: &protocol.SymbolInformation{\n\t\t\t\t\t\tName: \"Page\",\n\t\t\t\t\t\tKind: protocol.SymbolKindFunction,\n\t\t\t\t\t\tLocation: protocol.Location{\n\t\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\t\tStart: protocol.Position{Line: 11, Character: 0},\n\t\t\t\t\t\t\t\tEnd:   protocol.Position{Line: 50, Character: 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSymbolInformation: &protocol.SymbolInformation{\n\t\t\t\t\t\tName: \"nihao\",\n\t\t\t\t\t\tKind: protocol.SymbolKindVariable,\n\t\t\t\t\t\tLocation: protocol.Location{\n\t\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\t\tStart: protocol.Position{Line: 18, Character: 4},\n\t\t\t\t\t\t\t\tEnd:   protocol.Position{Line: 18, Character: 16},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSymbolInformation: &protocol.SymbolInformation{\n\t\t\t\t\t\tName: \"Struct\",\n\t\t\t\t\t\tKind: protocol.SymbolKindStruct,\n\t\t\t\t\t\tLocation: protocol.Location{\n\t\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\t\tStart: protocol.Position{Line: 20, Character: 5},\n\t\t\t\t\t\t\t\tEnd:   protocol.Position{Line: 22, Character: 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSymbolInformation: &protocol.SymbolInformation{\n\t\t\t\t\t\tName: \"s\",\n\t\t\t\t\t\tKind: protocol.SymbolKindVariable,\n\t\t\t\t\t\tLocation: protocol.Location{\n\t\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\t\tStart: protocol.Position{Line: 24, Character: 4},\n\t\t\t\t\t\t\t\tEnd:   protocol.Position{Line: 24, Character: 16},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\turi: \"file://\" + appDir + \"/remoteparent.templ\",\n\t\t\texpect: []protocol.SymbolInformationOrDocumentSymbol{\n\t\t\t\t{\n\t\t\t\t\tSymbolInformation: &protocol.SymbolInformation{\n\t\t\t\t\t\tName: \"RemoteInclusionTest\",\n\t\t\t\t\t\tKind: protocol.SymbolKindFunction,\n\t\t\t\t\t\tLocation: protocol.Location{\n\t\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\t\tStart: protocol.Position{Line: 9, Character: 0},\n\t\t\t\t\t\t\t\tEnd:   protocol.Position{Line: 35, Character: 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSymbolInformation: &protocol.SymbolInformation{\n\t\t\t\t\t\tName: \"Remote2\",\n\t\t\t\t\t\tKind: protocol.SymbolKindFunction,\n\t\t\t\t\t\tLocation: protocol.Location{\n\t\t\t\t\t\t\tRange: protocol.Range{\n\t\t\t\t\t\t\t\tStart: protocol.Position{Line: 37, Character: 0},\n\t\t\t\t\t\t\t\tEnd:   protocol.Position{Line: 63, Character: 1},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor i, test := range tests {\n\t\tt.Run(fmt.Sprintf(\"test-%d\", i), func(t *testing.T) {\n\t\t\tactual, err := server.DocumentSymbol(ctx, &protocol.DocumentSymbolParams{\n\t\t\t\tTextDocument: protocol.TextDocumentIdentifier{\n\t\t\t\t\tURI: uri.URI(test.uri),\n\t\t\t\t},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to get document symbol: %v\", err)\n\t\t\t}\n\n\t\t\t// Set expected URI.\n\t\t\tfor i, v := range test.expect {\n\t\t\t\tif v.SymbolInformation != nil {\n\t\t\t\t\tv.SymbolInformation.Location.URI = uri.URI(test.uri)\n\t\t\t\t\ttest.expect[i] = v\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to convert expect to any slice: %v\", err)\n\t\t\t}\n\t\t\tdiff := cmp.Diff(test.expect, actual)\n\t\t\tif diff != \"\" {\n\t\t\t\tt.Errorf(\"unexpected document symbol: %v\", diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc runeIndexToUTF8ByteIndex(s string, runeIndex int) (lspChar uint32, err error) {\n\tfor i, r := range []rune(s) {\n\t\tif i == runeIndex {\n\t\t\tbreak\n\t\t}\n\t\tl := utf8.RuneLen(r)\n\t\tif l < 0 {\n\t\t\treturn 0, fmt.Errorf(\"invalid rune in string at index %d\", runeIndex)\n\t\t}\n\t\tlspChar += uint32(l)\n\t}\n\treturn lspChar, nil\n}\n\nfunc NewTestClient(log *slog.Logger) TestClient {\n\treturn TestClient{\n\t\tlog: log,\n\t}\n}\n\ntype TestClient struct {\n\tlog *slog.Logger\n}\n\nfunc (tc TestClient) Progress(ctx context.Context, params *protocol.ProgressParams) (err error) {\n\ttc.log.Info(\"client: Received Progress\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) WorkDoneProgressCreate(ctx context.Context, params *protocol.WorkDoneProgressCreateParams) (err error) {\n\ttc.log.Info(\"client: Received WorkDoneProgressCreate\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) LogMessage(ctx context.Context, params *protocol.LogMessageParams) (err error) {\n\ttc.log.Info(\"client: Received LogMessage\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) PublishDiagnostics(ctx context.Context, params *protocol.PublishDiagnosticsParams) (err error) {\n\ttc.log.Info(\"client: Received PublishDiagnostics\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) ShowMessage(ctx context.Context, params *protocol.ShowMessageParams) (err error) {\n\ttc.log.Info(\"client: Received ShowMessage\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) ShowMessageRequest(ctx context.Context, params *protocol.ShowMessageRequestParams) (result *protocol.MessageActionItem, err error) {\n\treturn nil, nil\n}\n\nfunc (tc TestClient) Telemetry(ctx context.Context, params any) (err error) {\n\ttc.log.Info(\"client: Received Telemetry\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) RegisterCapability(ctx context.Context, params *protocol.RegistrationParams,\n) (err error) {\n\ttc.log.Info(\"client: Received RegisterCapability\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) UnregisterCapability(ctx context.Context, params *protocol.UnregistrationParams) (err error) {\n\ttc.log.Info(\"client: Received UnregisterCapability\", slog.Any(\"params\", params))\n\treturn nil\n}\n\nfunc (tc TestClient) ApplyEdit(ctx context.Context, params *protocol.ApplyWorkspaceEditParams) (result *protocol.ApplyWorkspaceEditResponse, err error) {\n\ttc.log.Info(\"client: Received ApplyEdit\", slog.Any(\"params\", params))\n\treturn nil, nil\n}\n\nfunc (tc TestClient) Configuration(ctx context.Context, params *protocol.ConfigurationParams) (result []any, err error) {\n\ttc.log.Info(\"client: Received Configuration\", slog.Any(\"params\", params))\n\treturn nil, nil\n}\n\nfunc (tc TestClient) WorkspaceFolders(ctx context.Context) (result []protocol.WorkspaceFolder, err error) {\n\ttc.log.Info(\"client: Received WorkspaceFolders\")\n\treturn nil, nil\n}\n\nfunc Setup(ctx context.Context, log *slog.Logger) (clientCtx context.Context, appDir string, client protocol.Client, server protocol.Server, teardown func(t *testing.T), err error) {\n\twd, err := os.Getwd()\n\tif err != nil {\n\t\treturn ctx, appDir, client, server, teardown, fmt.Errorf(\"could not find working dir: %w\", err)\n\t}\n\tmoduleRoot, err := modcheck.WalkUp(wd)\n\tif err != nil {\n\t\treturn ctx, appDir, client, server, teardown, fmt.Errorf(\"could not find local templ go.mod file: %v\", err)\n\t}\n\n\tappDir, err = testproject.Create(moduleRoot)\n\tif err != nil {\n\t\treturn ctx, appDir, client, server, teardown, fmt.Errorf(\"failed to create test project: %v\", err)\n\t}\n\n\tvar wg sync.WaitGroup\n\tvar cmdErr error\n\n\t// Copy from the LSP to the Client, and vice versa.\n\tfromClient, toLSP := io.Pipe()\n\tfromLSP, toClient := io.Pipe()\n\tclientStream := jsonrpc2.NewStream(newStdRwc(log, \"clientStream\", toLSP, fromLSP))\n\tserverStream := jsonrpc2.NewStream(newStdRwc(log, \"serverStream\", toClient, fromClient))\n\n\t// Create the client that the server needs.\n\tclient = NewTestClient(log)\n\tctx, _, server = protocol.NewClient(ctx, client, clientStream, log)\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tlog.Info(\"Running\")\n\t\t// Create the server that the client needs.\n\t\tcmdErr = run(ctx, log, serverStream, Arguments{})\n\t\tif cmdErr != nil {\n\t\t\tlog.Error(\"Failed to run\", slog.Any(\"error\", cmdErr))\n\t\t}\n\t\tlog.Info(\"Stopped\")\n\t}()\n\n\t// Initialize.\n\tir, err := server.Initialize(ctx, &protocol.InitializeParams{\n\t\tClientInfo: &protocol.ClientInfo{},\n\t\tCapabilities: protocol.ClientCapabilities{\n\t\t\tWorkspace: &protocol.WorkspaceClientCapabilities{\n\t\t\t\tApplyEdit: true,\n\t\t\t\tWorkspaceEdit: &protocol.WorkspaceClientCapabilitiesWorkspaceEdit{\n\t\t\t\t\tDocumentChanges: true,\n\t\t\t\t},\n\t\t\t\tWorkspaceFolders: true,\n\t\t\t\tFileOperations: &protocol.WorkspaceClientCapabilitiesFileOperations{\n\t\t\t\t\tDidCreate:  true,\n\t\t\t\t\tWillCreate: true,\n\t\t\t\t\tDidRename:  true,\n\t\t\t\t\tWillRename: true,\n\t\t\t\t\tDidDelete:  true,\n\t\t\t\t\tWillDelete: true,\n\t\t\t\t},\n\t\t\t},\n\t\t\tTextDocument: &protocol.TextDocumentClientCapabilities{\n\t\t\t\tSynchronization: &protocol.TextDocumentSyncClientCapabilities{\n\t\t\t\t\tDidSave: true,\n\t\t\t\t},\n\t\t\t\tCompletion: &protocol.CompletionTextDocumentClientCapabilities{\n\t\t\t\t\tCompletionItem: &protocol.CompletionTextDocumentClientCapabilitiesItem{\n\t\t\t\t\t\tSnippetSupport:       true,\n\t\t\t\t\t\tDeprecatedSupport:    true,\n\t\t\t\t\t\tInsertReplaceSupport: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tHover:              &protocol.HoverTextDocumentClientCapabilities{},\n\t\t\t\tSignatureHelp:      &protocol.SignatureHelpTextDocumentClientCapabilities{},\n\t\t\t\tDeclaration:        &protocol.DeclarationTextDocumentClientCapabilities{},\n\t\t\t\tDefinition:         &protocol.DefinitionTextDocumentClientCapabilities{},\n\t\t\t\tTypeDefinition:     &protocol.TypeDefinitionTextDocumentClientCapabilities{},\n\t\t\t\tImplementation:     &protocol.ImplementationTextDocumentClientCapabilities{},\n\t\t\t\tReferences:         &protocol.ReferencesTextDocumentClientCapabilities{},\n\t\t\t\tDocumentHighlight:  &protocol.DocumentHighlightClientCapabilities{},\n\t\t\t\tDocumentSymbol:     &protocol.DocumentSymbolClientCapabilities{},\n\t\t\t\tCodeAction:         &protocol.CodeActionClientCapabilities{},\n\t\t\t\tCodeLens:           &protocol.CodeLensClientCapabilities{},\n\t\t\t\tFormatting:         &protocol.DocumentFormattingClientCapabilities{},\n\t\t\t\tRangeFormatting:    &protocol.DocumentRangeFormattingClientCapabilities{},\n\t\t\t\tOnTypeFormatting:   &protocol.DocumentOnTypeFormattingClientCapabilities{},\n\t\t\t\tPublishDiagnostics: &protocol.PublishDiagnosticsClientCapabilities{},\n\t\t\t\tRename:             &protocol.RenameClientCapabilities{},\n\t\t\t\tFoldingRange:       &protocol.FoldingRangeClientCapabilities{},\n\t\t\t\tSelectionRange:     &protocol.SelectionRangeClientCapabilities{},\n\t\t\t\tCallHierarchy:      &protocol.CallHierarchyClientCapabilities{},\n\t\t\t\tSemanticTokens:     &protocol.SemanticTokensClientCapabilities{},\n\t\t\t\tLinkedEditingRange: &protocol.LinkedEditingRangeClientCapabilities{},\n\t\t\t},\n\t\t\tWindow:       &protocol.WindowClientCapabilities{},\n\t\t\tGeneral:      &protocol.GeneralClientCapabilities{},\n\t\t\tExperimental: nil,\n\t\t},\n\t\tWorkspaceFolders: []protocol.WorkspaceFolder{\n\t\t\t{\n\t\t\t\tURI:  \"file://\" + appDir,\n\t\t\t\tName: \"templ-test\",\n\t\t\t},\n\t\t},\n\t})\n\tif err != nil {\n\t\tlog.Error(\"Failed to init\", slog.Any(\"error\", err))\n\t}\n\tif ir.ServerInfo.Name != \"templ-lsp\" {\n\t\treturn ctx, appDir, client, server, teardown, fmt.Errorf(\"expected server name to be templ-lsp, got %q\", ir.ServerInfo.Name)\n\t}\n\n\t// Confirm initialization.\n\tlog.Info(\"Confirming initialization...\")\n\tif err = server.Initialized(ctx, &protocol.InitializedParams{}); err != nil {\n\t\treturn ctx, appDir, client, server, teardown, fmt.Errorf(\"failed to confirm initialization: %v\", err)\n\t}\n\tlog.Info(\"Initialized\")\n\n\t// Wait for exit.\n\tteardown = func(t *testing.T) {\n\t\tlog.Info(\"Tearing down LSP\")\n\t\twg.Wait()\n\t\tif cmdErr != nil {\n\t\t\tt.Errorf(\"failed to run lsp cmd: %v\", err)\n\t\t}\n\n\t\tif err = os.RemoveAll(appDir); err != nil {\n\t\t\tt.Errorf(\"failed to remove test dir %q: %v\", appDir, err)\n\t\t}\n\t}\n\treturn ctx, appDir, client, server, teardown, err\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/lspdiff/lspdiff.go",
    "content": "package lspdiff\n\nimport (\n\t\"github.com/a-h/templ/lsp/protocol\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n)\n\n// This package provides a way to compare LSP\tprotocol messages, ignoring irrelevant fields.\n\nfunc CodeAction(expected, actual []protocol.CodeAction) string {\n\treturn cmp.Diff(expected, actual)\n}\n\nfunc CompletionList(expected, actual *protocol.CompletionList) string {\n\treturn cmp.Diff(expected, actual,\n\t\tcmpopts.IgnoreFields(protocol.CompletionList{}, \"IsIncomplete\"),\n\t)\n}\n\nfunc References(expected, actual []protocol.Location) string {\n\treturn cmp.Diff(expected, actual)\n}\n\nfunc CompletionListContainsText(cl *protocol.CompletionList, text string) bool {\n\tif cl == nil {\n\t\treturn false\n\t}\n\tfor _, item := range cl.Items {\n\t\tif item.Label == text {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/main.go",
    "content": "package lspcmd\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\n\t\"github.com/a-h/templ/cmd/templ/lspcmd/httpdebug\"\n\t\"github.com/a-h/templ/cmd/templ/lspcmd/pls\"\n\t\"github.com/a-h/templ/cmd/templ/lspcmd/proxy\"\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n\t\"github.com/a-h/templ/lsp/protocol\"\n\n\t_ \"net/http/pprof\"\n)\n\ntype Arguments struct {\n\tLog           string\n\tGoplsLog      string\n\tGoplsRPCTrace bool\n\tGoplsRemote   string\n\t// PPROF sets whether to start a profiling server on localhost:9999\n\tPPROF bool\n\t// HTTPDebug sets the HTTP endpoint to listen on. Leave empty for no web debug.\n\tHTTPDebug string\n\t// NoPreload disables preloading of templ files on server startup (useful for large monorepos)\n\tNoPreload bool\n}\n\nfunc Run(stdin io.Reader, stdout, stderr io.Writer, args Arguments) (err error) {\n\tctx := context.Background()\n\tctx, cancel := context.WithCancel(ctx)\n\tsignalChan := make(chan os.Signal, 1)\n\tsignal.Notify(signalChan, os.Interrupt)\n\tdefer func() {\n\t\tsignal.Stop(signalChan)\n\t\tcancel()\n\t}()\n\tif args.PPROF {\n\t\tgo func() {\n\t\t\t_ = http.ListenAndServe(\"localhost:9999\", nil)\n\t\t}()\n\t}\n\tgo func() {\n\t\tselect {\n\t\tcase <-signalChan: // First signal, cancel context.\n\t\t\tcancel()\n\t\tcase <-ctx.Done():\n\t\t}\n\t\t<-signalChan // Second signal, hard exit.\n\t\tos.Exit(2)\n\t}()\n\tlog := slog.New(slog.NewJSONHandler(io.Discard, nil))\n\tif args.Log != \"\" {\n\t\tfile, err := os.OpenFile(args.Log, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to open log file: %w\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\t_ = file.Close()\n\t\t}()\n\n\t\t// Create a new logger with a file writer\n\t\tlog = slog.New(slog.NewJSONHandler(file, nil))\n\t\tlog.Debug(\"Logging to file\", slog.String(\"file\", args.Log))\n\t}\n\ttemplStream := jsonrpc2.NewStream(newStdRwc(log, \"templStream\", stdout, stdin))\n\treturn run(ctx, log, templStream, args)\n}\n\nfunc run(ctx context.Context, log *slog.Logger, templStream jsonrpc2.Stream, args Arguments) (err error) {\n\tlog.Info(\"lsp: starting up...\")\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tlog.Error(\"handled panic\", slog.Any(\"recovered\", r))\n\t\t}\n\t}()\n\n\tlog.Info(\"lsp: starting gopls...\")\n\trwc, err := pls.NewGopls(ctx, log, pls.Options{\n\t\tLog:      args.GoplsLog,\n\t\tRPCTrace: args.GoplsRPCTrace,\n\t\tRemote:   args.GoplsRemote,\n\t})\n\tif err != nil {\n\t\tlog.Error(\"failed to start gopls\", slog.Any(\"error\", err))\n\t\tos.Exit(1)\n\t}\n\n\tcache := proxy.NewSourceMapCache()\n\tdiagnosticCache := proxy.NewDiagnosticCache()\n\n\tlog.Info(\"creating gopls client\")\n\tclientProxy, clientInit := proxy.NewClient(log, cache, diagnosticCache)\n\t_, goplsConn, goplsServer := protocol.NewClient(ctx, clientProxy, jsonrpc2.NewStream(rwc), log)\n\tdefer func() {\n\t\tif closeErr := goplsConn.Close(); closeErr != nil {\n\t\t\tlog.Error(\"failed to close gopls connection\", slog.Any(\"error\", closeErr))\n\t\t}\n\t}()\n\n\tlog.Info(\"creating proxy\")\n\t// Create the proxy to sit between.\n\tserverProxy := proxy.NewServer(log, goplsServer, cache, diagnosticCache, args.NoPreload)\n\n\t// Create templ server.\n\tlog.Info(\"creating templ server\")\n\t_, templConn, templClient := protocol.NewServer(context.Background(), serverProxy, templStream, log)\n\tdefer func() {\n\t\tif err = templConn.Close(); err != nil {\n\t\t\tlog.Error(\"failed to close templ connection\", slog.Any(\"error\", err))\n\t\t}\n\t}()\n\n\t// Allow both the server and the client to initiate outbound requests.\n\tclientInit(templClient)\n\n\t// Start the web server if required.\n\tif args.HTTPDebug != \"\" {\n\t\tlog.Info(\"starting debug http server\", slog.String(\"addr\", args.HTTPDebug))\n\t\th := httpdebug.NewHandler(log, serverProxy)\n\t\tgo func() {\n\t\t\tif err := http.ListenAndServe(args.HTTPDebug, h); err != nil {\n\t\t\t\tlog.Error(\"web server failed\", slog.Any(\"error\", err))\n\t\t\t}\n\t\t}()\n\t}\n\n\tlog.Info(\"listening\")\n\n\tselect {\n\tcase <-ctx.Done():\n\t\tlog.Info(\"context closed\")\n\tcase <-templConn.Done():\n\t\tlog.Info(\"templConn closed\")\n\tcase <-goplsConn.Done():\n\t\tlog.Info(\"goplsConn closed\")\n\t}\n\tlog.Info(\"shutdown complete\")\n\treturn\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/pls/main.go",
    "content": "package pls\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"runtime\"\n)\n\n// Options for the gopls client.\ntype Options struct {\n\tLog      string\n\tRPCTrace bool\n\tRemote   string\n}\n\n// AsArguments converts the options into command line arguments for gopls.\nfunc (opts Options) AsArguments() []string {\n\tvar args []string\n\tif opts.Log != \"\" {\n\t\targs = append(args, \"-logfile\", opts.Log)\n\t}\n\tif opts.RPCTrace {\n\t\targs = append(args, \"-rpc.trace\")\n\t}\n\tif opts.Remote != \"\" {\n\t\targs = append(args, \"-remote\", opts.Remote)\n\t}\n\treturn args\n}\n\nfunc FindGopls() (location string, err error) {\n\texecutableName := \"gopls\"\n\tif runtime.GOOS == \"windows\" {\n\t\texecutableName = \"gopls.exe\"\n\t}\n\n\tpathLocation, err := exec.LookPath(executableName)\n\tif err == nil {\n\t\t// Found on the path.\n\t\treturn pathLocation, nil\n\t}\n\t// Unexpected error.\n\tif !errors.Is(err, exec.ErrNotFound) {\n\t\treturn \"\", fmt.Errorf(\"unexpected error looking for gopls: %w\", err)\n\t}\n\n\thome, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unexpected error looking for gopls: %w\", err)\n\t}\n\n\t// Probe standard locations.\n\tlocations := []string{\n\t\tpath.Join(home, \"go\", \"bin\", executableName),\n\t\tpath.Join(home, \".local\", \"bin\", executableName),\n\t}\n\tfor _, location := range locations {\n\t\t_, err = os.Stat(location)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\t// Found in a standard location.\n\t\treturn location, nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"cannot find gopls on the path (%q), in $HOME/go/bin or $HOME/.local/bin/gopls. You can install gopls with `go install golang.org/x/tools/gopls@latest`\", os.Getenv(\"PATH\"))\n}\n\n// NewGopls starts gopls and opens up a jsonrpc2 connection to it.\nfunc NewGopls(ctx context.Context, log *slog.Logger, opts Options) (rwc io.ReadWriteCloser, err error) {\n\tlocation, err := FindGopls()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcmd := exec.Command(location, opts.AsArguments()...)\n\treturn newProcessReadWriteCloser(log, cmd)\n}\n\n// newProcessReadWriteCloser creates a processReadWriteCloser to allow stdin/stdout to be used as\n// a JSON RPC 2.0 transport.\nfunc newProcessReadWriteCloser(logger *slog.Logger, cmd *exec.Cmd) (rwc processReadWriteCloser, err error) {\n\tstdin, err := cmd.StdinPipe()\n\tif err != nil {\n\t\treturn\n\t}\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn\n\t}\n\trwc = processReadWriteCloser{\n\t\tin:  stdin,\n\t\tout: stdout,\n\t}\n\tgo func() {\n\t\tif err := cmd.Run(); err != nil {\n\t\t\tlogger.Error(\"gopls command error\", slog.Any(\"error\", err))\n\t\t}\n\t}()\n\treturn\n}\n\ntype processReadWriteCloser struct {\n\tin  io.WriteCloser\n\tout io.ReadCloser\n}\n\nfunc (prwc processReadWriteCloser) Read(p []byte) (n int, err error) {\n\treturn prwc.out.Read(p)\n}\n\nfunc (prwc processReadWriteCloser) Write(p []byte) (n int, err error) {\n\treturn prwc.in.Write(p)\n}\n\nfunc (prwc processReadWriteCloser) Close() error {\n\terrInClose := prwc.in.Close()\n\terrOutClose := prwc.out.Close()\n\tif errInClose != nil || errOutClose != nil {\n\t\treturn fmt.Errorf(\"error closing process - in: %v, out: %v\", errInClose, errOutClose)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/client.go",
    "content": "package proxy\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"strings\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n)\n\n// Client is responsible for rewriting messages that are\n// originated from gopls, and are sent to the client.\n//\n// Since `gopls` is working on Go files, and this is the `templ` LSP,\n// the job of this code is to rewrite incoming requests to adjust the\n// file name from `*_templ.go` to `*.templ`, and to remap the char\n// positions where required.\ntype Client struct {\n\tLog             *slog.Logger\n\tTarget          lsp.Client\n\tSourceMapCache  *SourceMapCache\n\tDiagnosticCache *DiagnosticCache\n}\n\nfunc NewClient(log *slog.Logger, cache *SourceMapCache, diagnosticCache *DiagnosticCache) (c *Client, init func(lsp.Client)) {\n\tc = &Client{\n\t\tLog:             log,\n\t\tSourceMapCache:  cache,\n\t\tDiagnosticCache: diagnosticCache,\n\t}\n\treturn c, func(target lsp.Client) {\n\t\tc.Target = target\n\t}\n}\n\nfunc (p Client) Progress(ctx context.Context, params *lsp.ProgressParams) (err error) {\n\tp.Log.Info(\"client <- server: Progress\")\n\treturn p.Target.Progress(ctx, params)\n}\n\nfunc (p Client) WorkDoneProgressCreate(ctx context.Context, params *lsp.WorkDoneProgressCreateParams) (err error) {\n\tp.Log.Info(\"client <- server: WorkDoneProgressCreate\")\n\treturn p.Target.WorkDoneProgressCreate(ctx, params)\n}\n\nfunc (p Client) LogMessage(ctx context.Context, params *lsp.LogMessageParams) (err error) {\n\tp.Log.Info(\"client <- server: LogMessage\", slog.String(\"message\", params.Message))\n\treturn p.Target.LogMessage(ctx, params)\n}\n\nfunc (p Client) PublishDiagnostics(ctx context.Context, params *lsp.PublishDiagnosticsParams) (err error) {\n\tp.Log.Info(\"client <- server: PublishDiagnostics\")\n\tif strings.HasSuffix(string(params.URI), \"go.mod\") {\n\t\tp.Log.Info(\"client <- server: PublishDiagnostics: skipping go.mod diagnostics\")\n\t\treturn nil\n\t}\n\t// Log diagnostics.\n\tfor i, diagnostic := range params.Diagnostics {\n\t\tp.Log.Info(fmt.Sprintf(\"client <- server: PublishDiagnostics: [%d]\", i), slog.Any(\"diagnostic\", diagnostic))\n\t}\n\t// Get the sourcemap from the cache.\n\turi := strings.TrimSuffix(string(params.URI), \"_templ.go\") + \".templ\"\n\tsourceMap, ok := p.SourceMapCache.Get(uri)\n\tif !ok {\n\t\tp.Log.Error(\"unable to complete because the sourcemap for the URI doesn't exist in the cache\", slog.String(\"uri\", uri))\n\t\treturn fmt.Errorf(\"unable to complete because the sourcemap for %q doesn't exist in the cache, has the didOpen notification been sent yet?\", uri)\n\t}\n\tparams.URI = lsp.DocumentURI(uri)\n\t// Rewrite the positions.\n\tfor i, item := range params.Diagnostics {\n\t\tstart, ok := sourceMap.SourcePositionFromTarget(item.Range.Start.Line, item.Range.Start.Character)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tif item.Range.Start.Line == item.Range.End.Line {\n\t\t\tlength := item.Range.End.Character - item.Range.Start.Character\n\t\t\titem.Range.Start.Line = start.Line\n\t\t\titem.Range.Start.Character = start.Col\n\t\t\titem.Range.End.Line = start.Line\n\t\t\titem.Range.End.Character = start.Col + length\n\t\t\tparams.Diagnostics[i] = item\n\t\t\tp.Log.Info(fmt.Sprintf(\"diagnostic [%d] rewritten\", i), slog.Any(\"diagnostic\", item))\n\t\t\tcontinue\n\t\t}\n\t\tend, ok := sourceMap.SourcePositionFromTarget(item.Range.End.Line, item.Range.End.Character)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\titem.Range.Start.Line = start.Line\n\t\titem.Range.Start.Character = start.Col\n\t\titem.Range.End.Line = end.Line\n\t\titem.Range.End.Character = end.Col\n\t\tparams.Diagnostics[i] = item\n\t\tp.Log.Info(fmt.Sprintf(\"diagnostic [%d] rewritten\", i), slog.Any(\"diagnostic\", item))\n\t}\n\tparams.Diagnostics = p.DiagnosticCache.AddTemplDiagnostics(uri, params.Diagnostics)\n\terr = p.Target.PublishDiagnostics(ctx, params)\n\treturn err\n}\n\nfunc (p Client) ShowMessage(ctx context.Context, params *lsp.ShowMessageParams) (err error) {\n\tp.Log.Info(\"client <- server: ShowMessage\", slog.String(\"message\", params.Message))\n\tif strings.HasPrefix(params.Message, \"Do not edit this file!\") {\n\t\treturn\n\t}\n\tif strings.HasPrefix(params.Message, \"Warning: editing\") {\n\t\treturn\n\t}\n\treturn p.Target.ShowMessage(ctx, params)\n}\n\nfunc (p Client) ShowMessageRequest(ctx context.Context, params *lsp.ShowMessageRequestParams) (result *lsp.MessageActionItem, err error) {\n\tp.Log.Info(\"client <- server: ShowMessageRequest\", slog.String(\"message\", params.Message))\n\treturn p.Target.ShowMessageRequest(ctx, params)\n}\n\nfunc (p Client) Telemetry(ctx context.Context, params any) (err error) {\n\tp.Log.Info(\"client <- server: Telemetry\")\n\treturn p.Target.Telemetry(ctx, params)\n}\n\nfunc (p Client) RegisterCapability(ctx context.Context, params *lsp.RegistrationParams) (err error) {\n\tp.Log.Info(\"client <- server: RegisterCapability\")\n\treturn p.Target.RegisterCapability(ctx, params)\n}\n\nfunc (p Client) UnregisterCapability(ctx context.Context, params *lsp.UnregistrationParams) (err error) {\n\tp.Log.Info(\"client <- server: UnregisterCapability\")\n\treturn p.Target.UnregisterCapability(ctx, params)\n}\n\nfunc (p Client) ApplyEdit(ctx context.Context, params *lsp.ApplyWorkspaceEditParams) (result *lsp.ApplyWorkspaceEditResponse, err error) {\n\tp.Log.Info(\"client <- server: ApplyEdit\")\n\treturn p.Target.ApplyEdit(ctx, params)\n}\n\nfunc (p Client) Configuration(ctx context.Context, params *lsp.ConfigurationParams) (result []any, err error) {\n\tp.Log.Info(\"client <- server: Configuration\")\n\treturn p.Target.Configuration(ctx, params)\n}\n\nfunc (p Client) WorkspaceFolders(ctx context.Context) (result []lsp.WorkspaceFolder, err error) {\n\tp.Log.Info(\"client <- server: WorkspaceFolders\")\n\treturn p.Target.WorkspaceFolders(ctx)\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/diagnosticcache.go",
    "content": "package proxy\n\nimport (\n\t\"sync\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n)\n\nfunc NewDiagnosticCache() *DiagnosticCache {\n\treturn &DiagnosticCache{\n\t\tm:     &sync.Mutex{},\n\t\tcache: make(map[string]fileDiagnostic),\n\t}\n}\n\ntype fileDiagnostic struct {\n\ttemplDiagnostics []lsp.Diagnostic\n\tgoplsDiagnostics []lsp.Diagnostic\n}\n\ntype DiagnosticCache struct {\n\tm     *sync.Mutex\n\tcache map[string]fileDiagnostic\n}\n\nfunc zeroLengthSliceIfNil(diags []lsp.Diagnostic) []lsp.Diagnostic {\n\tif diags == nil {\n\t\treturn make([]lsp.Diagnostic, 0)\n\t}\n\treturn diags\n}\n\nfunc (dc *DiagnosticCache) AddTemplDiagnostics(uri string, goDiagnostics []lsp.Diagnostic) []lsp.Diagnostic {\n\tgoDiagnostics = zeroLengthSliceIfNil(goDiagnostics)\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\tdiag := dc.cache[uri]\n\tdiag.goplsDiagnostics = goDiagnostics\n\tdiag.templDiagnostics = zeroLengthSliceIfNil(diag.templDiagnostics)\n\tdc.cache[uri] = diag\n\treturn append(diag.templDiagnostics, goDiagnostics...)\n}\n\nfunc (dc *DiagnosticCache) ClearTemplDiagnostics(uri string) {\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\tdiag := dc.cache[uri]\n\tdiag.templDiagnostics = make([]lsp.Diagnostic, 0)\n\tdc.cache[uri] = diag\n}\n\nfunc (dc *DiagnosticCache) AddGoDiagnostics(uri string, templDiagnostics []lsp.Diagnostic) []lsp.Diagnostic {\n\ttemplDiagnostics = zeroLengthSliceIfNil(templDiagnostics)\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\tdiag := dc.cache[uri]\n\tdiag.templDiagnostics = templDiagnostics\n\tdiag.goplsDiagnostics = zeroLengthSliceIfNil(diag.goplsDiagnostics)\n\tdc.cache[uri] = diag\n\treturn append(diag.goplsDiagnostics, templDiagnostics...)\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/documentcontents.go",
    "content": "package proxy\n\nimport (\n\t\"fmt\"\n\t\"log/slog\"\n\t\"strings\"\n\t\"sync\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n)\n\n// newDocumentContents creates a document content processing tool.\nfunc newDocumentContents(log *slog.Logger) *DocumentContents {\n\treturn &DocumentContents{\n\t\tm:             new(sync.Mutex),\n\t\turiToContents: make(map[string]*Document),\n\t\tlog:           log,\n\t}\n}\n\ntype DocumentContents struct {\n\tm             *sync.Mutex\n\turiToContents map[string]*Document\n\tlog           *slog.Logger\n}\n\n// Set the contents of a document.\nfunc (dc *DocumentContents) Set(uri string, d *Document) {\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\tdc.uriToContents[uri] = d\n}\n\n// Get the contents of a document.\nfunc (dc *DocumentContents) Get(uri string) (d *Document, ok bool) {\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\td, ok = dc.uriToContents[uri]\n\treturn\n}\n\n// Delete a document from memory.\nfunc (dc *DocumentContents) Delete(uri string) {\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\tdelete(dc.uriToContents, uri)\n}\n\nfunc (dc *DocumentContents) URIs() (uris []string) {\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\turis = make([]string, len(dc.uriToContents))\n\tvar i int\n\tfor k := range dc.uriToContents {\n\t\turis[i] = k\n\t\ti++\n\t}\n\treturn uris\n}\n\n// Apply changes to the document from the client, and return a list of change requests to send back to the client.\nfunc (dc *DocumentContents) Apply(uri string, changes []lsp.TextDocumentContentChangeEvent) (d *Document, err error) {\n\tdc.m.Lock()\n\tdefer dc.m.Unlock()\n\tvar ok bool\n\td, ok = dc.uriToContents[uri]\n\tif !ok {\n\t\terr = fmt.Errorf(\"document not found\")\n\t\treturn\n\t}\n\tfor _, change := range changes {\n\t\td.Apply(change.Range, change.Text)\n\t}\n\treturn\n}\n\nfunc NewDocument(log *slog.Logger, s string) *Document {\n\treturn &Document{\n\t\tLog:   log,\n\t\tLines: strings.Split(s, \"\\n\"),\n\t}\n}\n\ntype Document struct {\n\tLog   *slog.Logger\n\tLines []string\n}\n\nfunc (d *Document) LineLengths() (lens []int) {\n\tlens = make([]int, len(d.Lines))\n\tfor i, l := range d.Lines {\n\t\tlens[i] = len(l)\n\t}\n\treturn\n}\n\nfunc (d *Document) Len() (line, col int) {\n\tline = len(d.Lines)\n\tcol = len(d.Lines[len(d.Lines)-1])\n\treturn\n}\n\nfunc (d *Document) Overwrite(fromLine, fromCol, toLine, toCol int, lines []string) {\n\tsuffix := d.Lines[toLine][toCol:]\n\ttoLen := d.LineLengths()[toLine]\n\td.Delete(fromLine, fromCol, toLine, toLen)\n\tlines[len(lines)-1] = lines[len(lines)-1] + suffix\n\td.Insert(fromLine, fromCol, lines)\n}\n\nfunc (d *Document) Insert(line, col int, lines []string) {\n\tprefix := d.Lines[line][:col]\n\tsuffix := d.Lines[line][col:]\n\tlines[0] = prefix + lines[0]\n\td.Lines[line] = lines[0]\n\n\tif len(lines) > 1 {\n\t\td.InsertLines(line+1, lines[1:])\n\t}\n\n\td.Lines[line+len(lines)-1] = lines[len(lines)-1] + suffix\n}\n\nfunc (d *Document) InsertLines(i int, withLines []string) {\n\td.Lines = append(d.Lines[:i], append(withLines, d.Lines[i:]...)...)\n}\n\nfunc (d *Document) Delete(fromLine, fromCol, toLine, toCol int) {\n\tprefix := d.Lines[fromLine][:fromCol]\n\tsuffix := d.Lines[toLine][toCol:]\n\n\t// Delete intermediate lines.\n\tdeleteFrom := fromLine\n\tdeleteTo := fromLine + (toLine - fromLine)\n\td.DeleteLines(deleteFrom, deleteTo)\n\n\t// Merge the contents of the final line.\n\td.Lines[fromLine] = prefix + suffix\n}\n\nfunc (d *Document) DeleteLines(i, j int) {\n\td.Lines = append(d.Lines[:i], d.Lines[j:]...)\n}\n\nfunc (d *Document) String() string {\n\treturn strings.Join(d.Lines, \"\\n\")\n}\n\nfunc (d *Document) Replace(with string) {\n\td.Lines = strings.Split(with, \"\\n\")\n}\n\nfunc (d *Document) Apply(r *lsp.Range, with string) {\n\twithLines := strings.Split(with, \"\\n\")\n\td.normalize(r)\n\tif d.isWholeDocument(r) {\n\t\td.Lines = withLines\n\t\treturn\n\t}\n\tif d.isInsert(r, with) {\n\t\td.Insert(int(r.Start.Line), int(r.Start.Character), withLines)\n\t\treturn\n\t}\n\tif d.isDelete(r, with) {\n\t\td.Delete(int(r.Start.Line), int(r.Start.Character), int(r.End.Line), int(r.End.Character))\n\t\treturn\n\t}\n\tif d.isOverwrite(r, with) {\n\t\td.Overwrite(int(r.Start.Line), int(r.Start.Character), int(r.End.Line), int(r.End.Character), withLines)\n\t}\n}\n\nfunc (d *Document) normalize(r *lsp.Range) {\n\tif r == nil {\n\t\treturn\n\t}\n\tlens := d.LineLengths()\n\tif r.Start.Line >= uint32(len(lens)) {\n\t\tr.Start.Line = uint32(len(lens) - 1)\n\t\tr.Start.Character = uint32(lens[r.Start.Line])\n\t}\n\tif r.Start.Character > uint32(lens[r.Start.Line]) {\n\t\tr.Start.Character = uint32(lens[r.Start.Line])\n\t}\n\tif r.End.Line >= uint32(len(lens)) {\n\t\tr.End.Line = uint32(len(lens) - 1)\n\t\tr.End.Character = uint32(lens[r.End.Line])\n\t}\n\tif r.End.Character > uint32(lens[r.End.Line]) {\n\t\tr.End.Character = uint32(lens[r.End.Line])\n\t}\n}\n\nfunc (d *Document) isOverwrite(r *lsp.Range, with string) bool {\n\treturn (r.End.Line != r.Start.Line || r.Start.Character != r.End.Character) && with != \"\"\n}\n\nfunc (d *Document) isInsert(r *lsp.Range, with string) bool {\n\treturn r.End.Line == r.Start.Line && r.Start.Character == r.End.Character && with != \"\"\n}\n\nfunc (d *Document) isDelete(r *lsp.Range, with string) bool {\n\treturn (r.End.Line != r.Start.Line || r.Start.Character != r.End.Character) && with == \"\"\n}\n\nfunc (d *Document) isWholeDocument(r *lsp.Range) bool {\n\tif r == nil {\n\t\treturn true\n\t}\n\tif r.Start.Line != 0 || r.Start.Character != 0 {\n\t\treturn false\n\t}\n\tl, c := d.Len()\n\treturn r.End.Line == uint32(l) || r.End.Character == uint32(c)\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/documentcontents_test.go",
    "content": "package proxy\n\nimport (\n\t\"log/slog\"\n\t\"os\"\n\t\"testing\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestDocument(t *testing.T) {\n\ttests := []struct {\n\t\tname       string\n\t\tstart      string\n\t\toperations []func(d *Document)\n\t\texpected   string\n\t}{\n\t\t{\n\t\t\tname:  \"Replace all content if the range is nil\",\n\t\t\tstart: \"0\\n1\\n2\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(nil, \"replaced\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"replaced\",\n\t\t},\n\t\t{\n\t\t\tname:  \"If the range matches the length of the file, all of it is replaced\",\n\t\t\tstart: \"0\\n1\\n2\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"replaced\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"replaced\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can insert new text\",\n\t\t\tstart: ``,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"abc\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"abc\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can insert new text that ends with a newline\",\n\t\t\tstart: ``,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"abc\\n\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `abc\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"Can insert a new line at the end of existing text\",\n\t\t\tstart: `abc\n`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\\n\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `abc\n\n`,\n\t\t},\n\t\t{\n\t\t\tname:  \"Can insert a word at the start of existing text\",\n\t\t\tstart: `bc`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"a\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `abc`,\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove whole line\",\n\t\t\tstart: \"0\\n1\\n2\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"0\\n2\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove line prefix\",\n\t\t\tstart: \"abcdef\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"def\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove line substring\",\n\t\t\tstart: \"abcdef\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"abdef\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove line suffix\",\n\t\t\tstart: \"abcdef\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 6,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"abcd\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove across lines\",\n\t\t\tstart: \"0\\n1\\n22\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"0\\n2\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove part of two lines\",\n\t\t\tstart: \"Line one\\nLine two\\nLine three\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"Line three\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove all lines\",\n\t\t\tstart: \"0\\n1\\n2\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can replace line prefix\",\n\t\t\tstart: \"012345\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"ABCDEFG\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"ABCDEFG345\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can replace text across line boundaries\",\n\t\t\tstart: \"Line one\\nLine two\\nLine three\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \" one test\\nNew Line 2\\nNew line\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"Line one test\\nNew Line 2\\nNew line three\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can add new line to end of single line\",\n\t\t\tstart: `a`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\\nb\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"a\\nb\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Exceeding the col and line count rounds down to the end of the file\",\n\t\t\tstart: `a`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      200,\n\t\t\t\t\t\t\tCharacter: 600,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      300,\n\t\t\t\t\t\t\tCharacter: 1200,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\\nb\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"a\\nb\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove a line and add it back from the end of the previous line (insert)\",\n\t\t\tstart: \"a\\nb\\nc\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\t// Delete.\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t\t// Put it back.\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\\nb\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"a\\nb\\nc\",\n\t\t},\n\t\t{\n\t\t\tname:  \"Can remove a line and add it back from the end of the previous line (overwrite)\",\n\t\t\tstart: \"a\\nb\\nc\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\t// Delete.\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t\t// Put it back.\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\\nb\\n\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"a\\nb\\nc\",\n\t\t},\n\t\t{\n\t\t\tname: \"Add new line with indent to the end of the line\",\n\t\t\t// Based on log entry.\n\t\t\t// {\"level\":\"info\",\"ts\":\"2022-06-04T20:55:15+01:00\",\"caller\":\"proxy/server.go:391\",\"msg\":\"client -> server: DidChange\",\"params\":{\"textDocument\":{\"uri\":\"file:///Users/adrian/github.com/a-h/templ/generator/test-call/template.templ\",\"version\":2},\"contentChanges\":[{\"range\":{\"start\":{\"line\":4,\"character\":21},\"end\":{\"line\":4,\"character\":21}},\"text\":\"\\n\\t\\t\"}]}}\n\t\t\tstart: `package testcall\n\ntempl personTemplate(p person) {\n\t<div>\n\t\t<h1>{ p.name }</h1>\n\t</div>\n}\n`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      4,\n\t\t\t\t\t\t\tCharacter: 21,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      4,\n\t\t\t\t\t\t\tCharacter: 21,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\\n\\t\\t\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `package testcall\n\ntempl personTemplate(p person) {\n\t<div>\n\t\t<h1>{ p.name }</h1>\n\t\t\n\t</div>\n}\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"Recreate error smaller\",\n\t\t\t// Based on log entry.\n\t\t\t// {\"level\":\"info\",\"ts\":\"2022-06-04T20:55:15+01:00\",\"caller\":\"proxy/server.go:391\",\"msg\":\"client -> server: DidChange\",\"params\":{\"textDocument\":{\"uri\":\"file:///Users/adrian/github.com/a-h/templ/generator/test-call/template.templ\",\"version\":2},\"contentChanges\":[{\"range\":{\"start\":{\"line\":4,\"character\":21},\"end\":{\"line\":4,\"character\":21}},\"text\":\"\\n\\t\\t\"}]}}\n\t\t\tstart: \"line1\\n\\t\\tline2\\nline3\",\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\t// Remove \\t\\tline2\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t\t// Put it back.\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 5,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\t\"\\n\\t\\tline2\\n\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"line1\\n\\t\\tline2\\nline3\",\n\t\t},\n\t\t{\n\t\t\tname: \"Recreate error\",\n\t\t\t// Based on log entry.\n\t\t\t// {\"level\":\"info\",\"ts\":\"2022-06-04T20:55:15+01:00\",\"caller\":\"proxy/server.go:391\",\"msg\":\"client -> server: DidChange\",\"params\":{\"textDocument\":{\"uri\":\"file:///Users/adrian/github.com/a-h/templ/generator/test-call/template.templ\",\"version\":2},\"contentChanges\":[{\"range\":{\"start\":{\"line\":4,\"character\":21},\"end\":{\"line\":4,\"character\":21}},\"text\":\"\\n\\t\\t\"}]}}\n\t\t\tstart: ` <footer data-testid=\"footerTemplate\">\n\t\t<div>&copy; { fmt.Sprintf(\"%d\", time.Now().Year()) }</div>\n\t</footer>\n}\n`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\t// Remove <div>&copy; { fmt.Sprintf(\"%d\", time.Now().Year()) }</div>\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"\")\n\t\t\t\t\t// Put it back.\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 38,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\t\"\\n\\t\\t<div>&copy; { fmt.Sprintf(\\\"%d\\\", time.Now().Year()) }</div>\\n\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: ` <footer data-testid=\"footerTemplate\">\n\t\t<div>&copy; { fmt.Sprintf(\"%d\", time.Now().Year()) }</div>\n\t</footer>\n}\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"Insert at start of line\",\n\t\t\t// Based on log entry.\n\t\t\t// {\"level\":\"info\",\"ts\":\"2023-03-25T17:17:38Z\",\"caller\":\"proxy/server.go:393\",\"msg\":\"client -> server: DidChange\",\"params\":{\"textDocument\":{\"uri\":\"file:///Users/adrian/github.com/a-h/templ/generator/test-call/template.templ\",\"version\":5},\"contentChanges\":[{\"range\":{\"start\":{\"line\":6,\"character\":0},\"end\":{\"line\":6,\"character\":0}},\"text\":\"a\"}]}}\n\t\t\tstart: `b`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      0,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"a\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `ab`,\n\t\t},\n\t\t{\n\t\t\tname: \"Insert full new line\",\n\t\t\tstart: `a\nc\nd`,\n\t\t\toperations: []func(d *Document){\n\t\t\t\tfunc(d *Document) {\n\t\t\t\t\td.Apply(&lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\t\tLine:      1,\n\t\t\t\t\t\t\tCharacter: 0,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, \"b\\n\")\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `a\nb\nc\nd`,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tlogger := slog.New(slog.NewJSONHandler(os.Stderr, nil))\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\td := NewDocument(logger, tt.start)\n\t\t\tfor _, f := range tt.operations {\n\t\t\t\tf(d)\n\t\t\t}\n\t\t\tactual := d.String()\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/import_test.go",
    "content": "package proxy\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestFindLastImport(t *testing.T) {\n\ttests := []struct {\n\t\tname          string\n\t\ttemplContents string\n\t\tpackageName   string\n\t\texpected      string\n\t}{\n\t\t{\n\t\t\tname: \"if there are no imports, add a single line import\",\n\t\t\ttemplContents: `package main\n\ntempl example() {\n}\n`,\n\t\t\tpackageName: \"strings\",\n\t\t\texpected: `package main\n\nimport \"strings\"\n\ntempl example() {\n}\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"if there is an existing single-line imports, add one at the end\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\ntempl example() {\n}\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\ntempl example() {\n}\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"if there are multiple existing single-line imports, add one at the end\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\ntempl example() {\n}\n`,\n\t\t\tpackageName: \"time\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\nimport \"time\"\n\ntempl example() {\n}\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"if there are existing multi-line imports, add one at the end\",\n\t\t\ttemplContents: `package main\n\nimport (\n\t\"strings\"\n)\n\ntempl example() {\n}\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport (\n\t\"strings\"\n\t\"fmt\"\n)\n\ntempl example() {\n}\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"ignore imports that happen after templates\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\ntempl example() {\n}\n\nimport \"other\"\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\ntempl example() {\n}\n\nimport \"other\"\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"ignore imports that happen after funcs in the file\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\nfunc example() {\n}\n\nimport \"other\"\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\nfunc example() {\n}\n\nimport \"other\"\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"ignore imports that happen after css expressions in the file\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\ncss example() {\n}\n\nimport \"other\"\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\ncss example() {\n}\n\nimport \"other\"\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"ignore imports that happen after script expressions in the file\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\nscript example() {\n}\n\nimport \"other\"\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\nscript example() {\n}\n\nimport \"other\"\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"ignore imports that happen after var expressions in the file\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\nvar s string\n\nimport \"other\"\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\nvar s string\n\nimport \"other\"\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"ignore imports that happen after const expressions in the file\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\nconst s = \"test\"\n\nimport \"other\"\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\nconst s = \"test\"\n\nimport \"other\"\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"ignore imports that happen after type expressions in the file\",\n\t\t\ttemplContents: `package main\n\nimport \"strings\"\n\ntype Value int\n\nimport \"other\"\n`,\n\t\t\tpackageName: \"fmt\",\n\t\t\texpected: `package main\n\nimport \"strings\"\nimport \"fmt\"\n\ntype Value int\n\nimport \"other\"\n`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tlines := strings.Split(test.templContents, \"\\n\")\n\t\t\timp := addImport(lines, fmt.Sprintf(\"%q\", test.packageName))\n\t\t\ttextWithoutNewline := strings.TrimSuffix(imp.Text, \"\\n\")\n\t\t\tactualLines := append(lines[:imp.LineIndex], append([]string{textWithoutNewline}, lines[imp.LineIndex:]...)...)\n\t\t\tactual := strings.Join(actualLines, \"\\n\")\n\t\t\tif diff := cmp.Diff(test.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGetPackageFromItemDetail(t *testing.T) {\n\ttests := []struct {\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tinput:    `\"fmt\"`,\n\t\t\texpected: `\"fmt\"`,\n\t\t},\n\t\t{\n\t\t\tinput:    `func(state fmt.State, verb rune) string (from \"fmt\")`,\n\t\t\texpected: `\"fmt\"`,\n\t\t},\n\t\t{\n\t\t\tinput:    `non matching`,\n\t\t\texpected: `non matching`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.input, func(t *testing.T) {\n\t\t\tactual := getPackageFromItemDetail(test.input)\n\t\t\tif test.expected != actual {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", test.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/rewrite.go",
    "content": "package proxy\n\nimport (\n\t\"path\"\n\t\"strings\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n)\n\nfunc convertTemplToGoURI(templURI lsp.DocumentURI) (isTemplFile bool, goURI lsp.DocumentURI) {\n\tbase, fileName := path.Split(string(templURI))\n\tif !strings.HasSuffix(fileName, \".templ\") {\n\t\treturn\n\t}\n\treturn true, lsp.DocumentURI(base + (strings.TrimSuffix(fileName, \".templ\") + \"_templ.go\"))\n}\n\nfunc convertTemplGoToTemplURI(goURI lsp.DocumentURI) (isTemplGoFile bool, templURI lsp.DocumentURI) {\n\tbase, fileName := path.Split(string(goURI))\n\tif !strings.HasSuffix(fileName, \"_templ.go\") {\n\t\treturn\n\t}\n\treturn true, lsp.DocumentURI(base + (strings.TrimSuffix(fileName, \"_templ.go\") + \".templ\"))\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/server.go",
    "content": "package proxy\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/internal/imports\"\n\t\"github.com/a-h/templ/internal/lazyloader\"\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n\t\"github.com/a-h/templ/lsp/uri\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator\"\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\n// Server is responsible for rewriting messages that are\n// originated from the text editor, and need to be sent to gopls.\n//\n// Since the editor is working on `templ` files, and `gopls` works\n// on Go files, the job of this code is to rewrite incoming requests\n// to adjust the file names from `*.templ` to `*_templ.go` and to\n// remap the line/character positions in the `templ` files to their\n// corresponding locations in the Go file.\n//\n// This allows gopls to operate as usual.\n//\n// This code also rewrites the responses back from gopls to do the\n// inverse operation - to put the file names back, and readjust any\n// character positions.\ntype Server struct {\n\tLog                *slog.Logger\n\tTarget             lsp.Server\n\tSourceMapCache     *SourceMapCache\n\tDiagnosticCache    *DiagnosticCache\n\tTemplSource        *DocumentContents\n\tGoSource           map[string]string\n\tNoPreload          bool\n\tpreLoadURIs        []*lsp.DidOpenTextDocumentParams\n\ttemplDocLazyLoader lazyloader.TemplDocLazyLoader\n}\n\nfunc NewServer(log *slog.Logger, target lsp.Server, cache *SourceMapCache, diagnosticCache *DiagnosticCache, noPreload bool) (s *Server) {\n\treturn &Server{\n\t\tLog:             log,\n\t\tTarget:          target,\n\t\tSourceMapCache:  cache,\n\t\tDiagnosticCache: diagnosticCache,\n\t\tTemplSource:     newDocumentContents(log),\n\t\tGoSource:        make(map[string]string),\n\t\tNoPreload:       noPreload,\n\t}\n}\n\n// updatePosition maps positions and filenames from source templ files into the target *.go files.\nfunc (p *Server) updatePosition(templURI lsp.DocumentURI, current lsp.Position) (ok bool, goURI lsp.DocumentURI, updated lsp.Position) {\n\tlog := p.Log.With(slog.String(\"uri\", string(templURI)))\n\tvar isTemplFile bool\n\tif isTemplFile, goURI = convertTemplToGoURI(templURI); !isTemplFile {\n\t\treturn false, templURI, current\n\t}\n\tsourceMap, ok := p.SourceMapCache.Get(string(templURI))\n\tif !ok {\n\t\tlog.Warn(\"completion: sourcemap not found in cache, it could be that didOpen was not called\")\n\t\treturn\n\t}\n\t// Map from the source position to target Go position.\n\tto, ok := sourceMap.TargetPositionFromSource(current.Line, current.Character)\n\tif !ok {\n\t\tlog.Info(\"updatePosition: not found\", slog.String(\"from\", fmt.Sprintf(\"%d:%d\", current.Line, current.Character)))\n\t\treturn false, templURI, current\n\t}\n\tlog.Info(\"updatePosition: found\", slog.String(\"fromTempl\", fmt.Sprintf(\"%d:%d\", current.Line, current.Character)),\n\t\tslog.String(\"toGo\", fmt.Sprintf(\"%d:%d\", to.Line, to.Col)))\n\tupdated.Line = to.Line\n\tupdated.Character = to.Col\n\n\treturn true, goURI, updated\n}\n\nfunc (p *Server) convertTemplRangeToGoRange(templURI lsp.DocumentURI, input lsp.Range) (output lsp.Range, ok bool) {\n\toutput = input\n\tvar sourceMap *parser.SourceMap\n\tsourceMap, ok = p.SourceMapCache.Get(string(templURI))\n\tif !ok {\n\t\tp.Log.Warn(\"templ->go: sourcemap not found in cache\")\n\t\treturn\n\t}\n\t// Map from the source position to target Go position.\n\tstart, ok := sourceMap.TargetPositionFromSource(input.Start.Line, input.Start.Character)\n\tif ok {\n\t\toutput.Start.Line = start.Line\n\t\toutput.Start.Character = start.Col\n\t}\n\tend, ok := sourceMap.TargetPositionFromSource(input.End.Line, input.End.Character)\n\tif ok {\n\t\toutput.End.Line = end.Line\n\t\toutput.End.Character = end.Col\n\t}\n\treturn\n}\n\nfunc (p *Server) convertGoRangeToTemplRange(templURI lsp.DocumentURI, input lsp.Range) (output lsp.Range) {\n\toutput = input\n\tsourceMap, ok := p.SourceMapCache.Get(string(templURI))\n\tif !ok {\n\t\tp.Log.Warn(\"go->templ: sourcemap not found in cache\")\n\t\treturn\n\t}\n\t// Map from the source position to target Go position.\n\tstart, startPositionMapped := sourceMap.SourcePositionFromTarget(input.Start.Line, input.Start.Character)\n\tif startPositionMapped {\n\t\toutput.Start.Line = start.Line\n\t\toutput.Start.Character = start.Col\n\t}\n\tend, endPositionMapped := sourceMap.SourcePositionFromTarget(input.End.Line, input.End.Character)\n\tif endPositionMapped {\n\t\toutput.End.Line = end.Line\n\t\toutput.End.Character = end.Col\n\t}\n\tif !startPositionMapped || !endPositionMapped {\n\t\tp.Log.Warn(\"go->templ: range not found in sourcemap\", slog.Any(\"range\", input))\n\t}\n\treturn\n}\n\n// parseTemplate parses the templ file content, and notifies the end user via the LSP about how it went.\nfunc (p *Server) parseTemplate(ctx context.Context, uri uri.URI, templateText string) (template *parser.TemplateFile, ok bool, err error) {\n\ttemplate, err = parser.ParseString(templateText)\n\tif err != nil {\n\t\tmsg := &lsp.PublishDiagnosticsParams{\n\t\t\tURI: uri,\n\t\t\tDiagnostics: []lsp.Diagnostic{\n\t\t\t\t{\n\t\t\t\t\tSeverity: lsp.DiagnosticSeverityError,\n\t\t\t\t\tCode:     \"\",\n\t\t\t\t\tSource:   \"templ\",\n\t\t\t\t\tMessage:  err.Error(),\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tif pe, isParserError := err.(parse.ParseError); isParserError {\n\t\t\tmsg.Diagnostics[0].Range = lsp.Range{\n\t\t\t\tStart: lsp.Position{\n\t\t\t\t\tLine:      uint32(pe.Pos.Line),\n\t\t\t\t\tCharacter: uint32(pe.Pos.Col),\n\t\t\t\t},\n\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\tLine:      uint32(pe.Pos.Line),\n\t\t\t\t\tCharacter: uint32(pe.Pos.Col),\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\tmsg.Diagnostics = p.DiagnosticCache.AddGoDiagnostics(string(uri), msg.Diagnostics)\n\t\terr = lsp.ClientFromContext(ctx).PublishDiagnostics(ctx, msg)\n\t\tif err != nil {\n\t\t\tp.Log.Error(\"failed to publish error diagnostics\", slog.Any(\"error\", err))\n\t\t}\n\t\t// If the template was even partially parsed, it's still potentially useful.\n\t\tif template != nil {\n\t\t\ttemplate.Filepath = string(uri)\n\t\t}\n\t\treturn\n\t}\n\ttemplate.Filepath = string(uri)\n\tparsedDiagnostics, err := parser.Diagnose(template)\n\tif err != nil {\n\t\treturn\n\t}\n\tok = true\n\tif len(parsedDiagnostics) > 0 {\n\t\tmsg := &lsp.PublishDiagnosticsParams{\n\t\t\tURI: uri,\n\t\t}\n\t\tfor _, d := range parsedDiagnostics {\n\t\t\tmsg.Diagnostics = append(msg.Diagnostics, lsp.Diagnostic{\n\t\t\t\tSeverity: lsp.DiagnosticSeverityWarning,\n\t\t\t\tCode:     \"\",\n\t\t\t\tSource:   \"templ\",\n\t\t\t\tMessage:  d.Message,\n\t\t\t\tRange: lsp.Range{\n\t\t\t\t\tStart: lsp.Position{\n\t\t\t\t\t\tLine:      uint32(d.Range.From.Line),\n\t\t\t\t\t\tCharacter: uint32(d.Range.From.Col),\n\t\t\t\t\t},\n\t\t\t\t\tEnd: lsp.Position{\n\t\t\t\t\t\tLine:      uint32(d.Range.To.Line),\n\t\t\t\t\t\tCharacter: uint32(d.Range.To.Col),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t\tmsg.Diagnostics = p.DiagnosticCache.AddGoDiagnostics(string(uri), msg.Diagnostics)\n\t\terr = lsp.ClientFromContext(ctx).PublishDiagnostics(ctx, msg)\n\t\tif err != nil {\n\t\t\tp.Log.Error(\"failed to publish error diagnostics\", slog.Any(\"error\", err))\n\t\t}\n\t\treturn\n\t}\n\t// Clear templ diagnostics.\n\tp.DiagnosticCache.ClearTemplDiagnostics(string(uri))\n\terr = lsp.ClientFromContext(ctx).PublishDiagnostics(ctx, &lsp.PublishDiagnosticsParams{\n\t\tURI: uri,\n\t\t// Cannot be nil as per https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#publishDiagnosticsParams\n\t\tDiagnostics: []lsp.Diagnostic{},\n\t})\n\tif err != nil {\n\t\tp.Log.Error(\"failed to publish diagnostics\", slog.Any(\"error\", err))\n\t\treturn\n\t}\n\treturn\n}\n\nfunc (p *Server) Initialize(ctx context.Context, params *lsp.InitializeParams) (result *lsp.InitializeResult, err error) {\n\tp.Log.Info(\"client -> server: Initialize\")\n\tdefer p.Log.Info(\"client -> server: Initialize end\")\n\tresult, err = p.Target.Initialize(ctx, params)\n\tif err != nil {\n\t\tp.Log.Error(\"Initialize failed\", slog.Any(\"error\", err))\n\t}\n\t// Add the '<' and '{' trigger so that we can do snippets for tags.\n\tif result.Capabilities.CompletionProvider == nil {\n\t\tresult.Capabilities.CompletionProvider = &lsp.CompletionOptions{}\n\t}\n\tresult.Capabilities.CompletionProvider.TriggerCharacters = append(result.Capabilities.CompletionProvider.TriggerCharacters, \"{\", \"<\")\n\t// Remove all the gopls commands.\n\tif result.Capabilities.ExecuteCommandProvider == nil {\n\t\tresult.Capabilities.ExecuteCommandProvider = &lsp.ExecuteCommandOptions{}\n\t}\n\tresult.Capabilities.ExecuteCommandProvider.Commands = []string{}\n\tresult.Capabilities.DocumentFormattingProvider = true\n\tresult.Capabilities.SemanticTokensProvider = nil\n\tresult.Capabilities.DocumentRangeFormattingProvider = false\n\tresult.Capabilities.TextDocumentSync = lsp.TextDocumentSyncOptions{\n\t\tOpenClose:         true,\n\t\tChange:            lsp.TextDocumentSyncKindFull,\n\t\tWillSave:          false,\n\t\tWillSaveWaitUntil: false,\n\t\tSave:              &lsp.SaveOptions{IncludeText: true},\n\t}\n\n\tif p.NoPreload {\n\t\tp.templDocLazyLoader = lazyloader.New(lazyloader.NewParams{\n\t\t\tTemplDocHandler: p,\n\t\t\tOpenDocSources:  p.GoSource,\n\t\t})\n\t} else {\n\t\tp.preload(ctx, params.WorkspaceFolders)\n\t}\n\n\tresult.ServerInfo.Name = \"templ-lsp\"\n\tresult.ServerInfo.Version = templ.Version()\n\n\treturn result, err\n}\n\nfunc (p *Server) preload(ctx context.Context, workspaceFolders []lsp.WorkspaceFolder) {\n\tfor _, c := range workspaceFolders {\n\t\tpath, err := uri.ParseDocumentURI(c.URI)\n\t\tif err != nil {\n\t\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", c.URI))\n\t\t\tcontinue\n\t\t}\n\n\t\twerr := filepath.Walk(path.Filename(), func(path string, info os.FileInfo, err error) error {\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tp.Log.Info(\"found file\", slog.String(\"path\", path))\n\t\t\turi := uri.URIFromPath(path)\n\t\t\tisTemplFile, goURI := convertTemplToGoURI(uri)\n\n\t\t\tif !isTemplFile {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tb, err := os.ReadFile(path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tp.TemplSource.Set(string(uri), NewDocument(p.Log, string(b)))\n\t\t\t// Parse the template.\n\t\t\ttemplate, _, err := p.parseTemplate(ctx, uri, string(b))\n\t\t\tif err != nil {\n\t\t\t\t// It's expected to have some failures while parsing the template, since\n\t\t\t\t// you are likely to have invalid docs while you're typing.\n\t\t\t\tp.Log.Info(\"parseTemplate failure\", slog.Any(\"error\", err))\n\t\t\t}\n\t\t\tw := new(strings.Builder)\n\t\t\tgeneratorOutput, err := generator.Generate(template, w)\n\t\t\tif err != nil {\n\t\t\t\t// It's expected to have some failures while generating code from the template, since\n\t\t\t\t// you are likely to have invalid docs while you're typing.\n\t\t\t\tp.Log.Info(\"generator failure\", slog.Any(\"error\", err))\n\t\t\t}\n\t\t\tp.Log.Info(\"setting source map cache contents\", slog.String(\"uri\", string(uri)))\n\t\t\tp.SourceMapCache.Set(string(uri), generatorOutput.SourceMap)\n\t\t\t// Set the Go contents.\n\t\t\tp.GoSource[string(uri)] = w.String()\n\n\t\t\tdidOpenParams := &lsp.DidOpenTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentItem{\n\t\t\t\t\tURI:        goURI,\n\t\t\t\t\tText:       w.String(),\n\t\t\t\t\tVersion:    1,\n\t\t\t\t\tLanguageID: \"go\",\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tp.preLoadURIs = append(p.preLoadURIs, didOpenParams)\n\t\t\treturn nil\n\t\t})\n\t\tif werr != nil {\n\t\t\tp.Log.Error(\"walk error\", slog.Any(\"error\", werr))\n\t\t}\n\t}\n}\n\nfunc (p *Server) Initialized(ctx context.Context, params *lsp.InitializedParams) (err error) {\n\tp.Log.Info(\"client -> server: Initialized\")\n\tdefer p.Log.Info(\"client -> server: Initialized end\")\n\tgoInitErr := p.Target.Initialized(ctx, params)\n\n\tfor i, doParams := range p.preLoadURIs {\n\t\tdoErr := p.Target.DidOpen(ctx, doParams)\n\t\tif doErr != nil {\n\t\t\treturn doErr\n\t\t}\n\t\tp.preLoadURIs[i] = nil\n\t}\n\n\treturn goInitErr\n}\n\nfunc (p *Server) Shutdown(ctx context.Context) (err error) {\n\tp.Log.Info(\"client -> server: Shutdown\")\n\tdefer p.Log.Info(\"client -> server: Shutdown end\")\n\treturn p.Target.Shutdown(ctx)\n}\n\nfunc (p *Server) Exit(ctx context.Context) (err error) {\n\tp.Log.Info(\"client -> server: Exit\")\n\tdefer p.Log.Info(\"client -> server: Exit end\")\n\treturn p.Target.Exit(ctx)\n}\n\nfunc (p *Server) WorkDoneProgressCancel(ctx context.Context, params *lsp.WorkDoneProgressCancelParams) (err error) {\n\tp.Log.Info(\"client -> server: WorkDoneProgressCancel\")\n\tdefer p.Log.Info(\"client -> server: WorkDoneProgressCancel end\")\n\treturn p.Target.WorkDoneProgressCancel(ctx, params)\n}\n\nfunc (p *Server) LogTrace(ctx context.Context, params *lsp.LogTraceParams) (err error) {\n\tp.Log.Info(\"client -> server: LogTrace\", slog.String(\"message\", params.Message))\n\tdefer p.Log.Info(\"client -> server: LogTrace end\")\n\treturn p.Target.LogTrace(ctx, params)\n}\n\nfunc (p *Server) SetTrace(ctx context.Context, params *lsp.SetTraceParams) (err error) {\n\tp.Log.Info(\"client -> server: SetTrace\")\n\tdefer p.Log.Info(\"client -> server: SetTrace end\")\n\treturn p.Target.SetTrace(ctx, params)\n}\n\nvar supportedCodeActions = map[string]bool{}\n\nfunc (p *Server) CodeAction(ctx context.Context, params *lsp.CodeActionParams) (result []lsp.CodeAction, err error) {\n\tp.Log.Info(\"client -> server: CodeAction\", slog.Any(\"params\", params))\n\tdefer p.Log.Info(\"client -> server: CodeAction end\")\n\n\tif p.NoPreload && !p.templDocLazyLoader.HasLoaded(params.TextDocument) {\n\t\tp.Log.Error(\"lazy loader has not loaded document\", slog.Any(\"params\", params))\n\t\treturn nil, nil\n\t}\n\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.CodeAction(ctx, params)\n\t}\n\tvar ok bool\n\tif params.Range, ok = p.convertTemplRangeToGoRange(templURI, params.Range); !ok {\n\t\t// Don't pass the request to gopls if the range is not within a Go code block.\n\t\treturn\n\t}\n\tparams.TextDocument.URI = goURI\n\tresult, err = p.Target.CodeAction(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar updatedResults []lsp.CodeAction\n\t// Filter out commands that are not yet supported.\n\t// For example, \"Fill Struct\" runs the `gopls.apply_fix` command.\n\t// This command has a set of arguments, including Fix, Range and URI.\n\t// However, these are just a map[string]any so for each command that we want to support,\n\t// we need to know what the arguments are so that we can rewrite them.\n\tfor _, r := range result {\n\t\tif !supportedCodeActions[r.Title] {\n\t\t\tcontinue\n\t\t}\n\t\t// Rewrite the Diagnostics range field.\n\t\tfor di, diag := range r.Diagnostics {\n\t\t\tr.Diagnostics[di].Range = p.convertGoRangeToTemplRange(templURI, diag.Range)\n\t\t}\n\t\t// Rewrite the DocumentChanges.\n\t\tif r.Edit != nil {\n\t\t\tfor dci, dc := range r.Edit.DocumentChanges {\n\t\t\t\tfor ei, edit := range dc.Edits {\n\t\t\t\t\tdc.Edits[ei].Range = p.convertGoRangeToTemplRange(templURI, edit.Range)\n\t\t\t\t}\n\t\t\t\tdc.TextDocument.URI = templURI\n\t\t\t\tr.Edit.DocumentChanges[dci] = dc\n\t\t\t}\n\t\t}\n\t\tupdatedResults = append(updatedResults, r)\n\t}\n\treturn updatedResults, nil\n}\n\nfunc (p *Server) CodeLens(ctx context.Context, params *lsp.CodeLensParams) (result []lsp.CodeLens, err error) {\n\tp.Log.Info(\"client -> server: CodeLens\")\n\tdefer p.Log.Info(\"client -> server: CodeLens end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.CodeLens(ctx, params)\n\t}\n\tparams.TextDocument.URI = goURI\n\tresult, err = p.Target.CodeLens(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\tfor i, cl := range result {\n\t\tcl.Range = p.convertGoRangeToTemplRange(templURI, cl.Range)\n\t\tresult[i] = cl\n\t}\n\treturn\n}\n\nfunc (p *Server) CodeLensResolve(ctx context.Context, params *lsp.CodeLens) (result *lsp.CodeLens, err error) {\n\tp.Log.Info(\"client -> server: CodeLensResolve\")\n\tdefer p.Log.Info(\"client -> server: CodeLensResolve end\")\n\treturn p.Target.CodeLensResolve(ctx, params)\n}\n\nfunc (p *Server) ColorPresentation(ctx context.Context, params *lsp.ColorPresentationParams) (result []lsp.ColorPresentation, err error) {\n\tp.Log.Info(\"client -> server: ColorPresentation ColorPresentation\")\n\tdefer p.Log.Info(\"client -> server: ColorPresentation end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.ColorPresentation(ctx, params)\n\t}\n\tparams.TextDocument.URI = goURI\n\tresult, err = p.Target.ColorPresentation(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\tfor i, r := range result {\n\t\tif r.TextEdit != nil {\n\t\t\tr.TextEdit.Range = p.convertGoRangeToTemplRange(templURI, r.TextEdit.Range)\n\t\t}\n\t\tresult[i] = r\n\t}\n\treturn\n}\n\nfunc (p *Server) Completion(ctx context.Context, params *lsp.CompletionParams) (result *lsp.CompletionList, err error) {\n\tp.Log.Info(\"client -> server: Completion\")\n\tdefer p.Log.Info(\"client -> server: Completion end\")\n\tif params.Context != nil && params.Context.TriggerCharacter == \"<\" {\n\t\tresult = &lsp.CompletionList{\n\t\t\tItems: htmlSnippets,\n\t\t}\n\t\treturn\n\t}\n\t// Get the sourcemap from the cache.\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\n\t// Ensure that Go source is available.\n\tgosrc := strings.Split(p.GoSource[string(templURI)], \"\\n\")\n\tif len(gosrc) < int(params.Position.Line) {\n\t\tp.Log.Info(\"completion: line position out of range\")\n\t\treturn nil, nil\n\t}\n\tif len(gosrc[params.Position.Line]) < int(params.Position.Character) {\n\t\tp.Log.Info(\"completion: col position out of range\")\n\t\treturn nil, nil\n\t}\n\n\t// Call the target.\n\tresult, err = p.Target.Completion(ctx, params)\n\tif err != nil {\n\t\tp.Log.Warn(\"completion: got gopls error\", slog.Any(\"error\", err))\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\t// Rewrite the result positions.\n\tp.Log.Info(\"completion: received items\", slog.Int(\"count\", len(result.Items)))\n\n\tfor i, item := range result.Items {\n\t\titem.FilterText = stripTemplStringable(item.FilterText)\n\t\tif item.TextEdit != nil {\n\t\t\tif item.TextEdit.TextEdit != nil {\n\t\t\t\titem.TextEdit.TextEdit.Range = p.convertGoRangeToTemplRange(templURI, item.TextEdit.TextEdit.Range)\n\t\t\t\titem.TextEdit.TextEdit.NewText = stripTemplStringable(item.TextEdit.TextEdit.NewText)\n\t\t\t}\n\t\t\tif item.TextEdit.InsertReplaceEdit != nil {\n\t\t\t\titem.TextEdit.InsertReplaceEdit.Insert = p.convertGoRangeToTemplRange(templURI, item.TextEdit.InsertReplaceEdit.Insert)\n\t\t\t\titem.TextEdit.InsertReplaceEdit.Replace = p.convertGoRangeToTemplRange(templURI, item.TextEdit.InsertReplaceEdit.Replace)\n\t\t\t\titem.TextEdit.InsertReplaceEdit.NewText = stripTemplStringable(item.TextEdit.InsertReplaceEdit.NewText)\n\t\t\t}\n\t\t}\n\t\tif len(item.AdditionalTextEdits) > 0 {\n\t\t\tdoc, ok := p.TemplSource.Get(string(templURI))\n\t\t\tif !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpkg := getPackageFromItemDetail(item.Detail)\n\t\t\timp := addImport(doc.Lines, pkg)\n\t\t\titem.AdditionalTextEdits = []lsp.TextEdit{\n\t\t\t\t{\n\t\t\t\t\tRange: lsp.Range{\n\t\t\t\t\t\tStart: lsp.Position{Line: uint32(imp.LineIndex), Character: 0},\n\t\t\t\t\t\tEnd:   lsp.Position{Line: uint32(imp.LineIndex), Character: 0},\n\t\t\t\t\t},\n\t\t\t\t\tNewText: imp.Text,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\tresult.Items[i] = item\n\t}\n\n\t// Add templ snippet.\n\tresult.Items = append(result.Items, snippet...)\n\n\treturn\n}\n\n// The LSP attempts to insert `templ.stringable(variable)` as a completion, but this isn't required.\nfunc stripTemplStringable(s string) string {\n\tif !strings.HasPrefix(s, \"templ.stringable(\") {\n\t\treturn s\n\t}\n\ts = strings.TrimPrefix(s, \"templ.stringable(\")\n\ts = strings.TrimSuffix(s, \")\")\n\treturn s\n}\n\nvar completionWithImport = regexp.MustCompile(`^.*\\(from\\s(\".+\")\\)$`)\n\nfunc getPackageFromItemDetail(pkg string) string {\n\tif m := completionWithImport.FindStringSubmatch(pkg); len(m) == 2 {\n\t\treturn m[1]\n\t}\n\treturn pkg\n}\n\ntype importInsert struct {\n\tText      string\n\tLineIndex int\n}\n\nvar nonImportKeywordRegexp = regexp.MustCompile(`^(?:templ|func|css|script|var|const|type)\\s`)\n\nfunc addImport(lines []string, pkg string) (result importInsert) {\n\tvar isInMultiLineImport bool\n\tlastSingleLineImportIndex := -1\n\tfor lineIndex, line := range lines {\n\t\tif strings.HasPrefix(line, \"import (\") {\n\t\t\tisInMultiLineImport = true\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"import \\\"\") {\n\t\t\tlastSingleLineImportIndex = lineIndex\n\t\t\tcontinue\n\t\t}\n\t\tif isInMultiLineImport && strings.HasPrefix(line, \")\") {\n\t\t\treturn importInsert{\n\t\t\t\tLineIndex: lineIndex,\n\t\t\t\tText:      fmt.Sprintf(\"\\t%s\\n\", pkg),\n\t\t\t}\n\t\t}\n\t\t// Only add import statements before templates, functions, css, and script templates.\n\t\tif nonImportKeywordRegexp.MatchString(line) {\n\t\t\tbreak\n\t\t}\n\t}\n\tvar suffix string\n\tif lastSingleLineImportIndex == -1 {\n\t\tlastSingleLineImportIndex = 1\n\t\tsuffix = \"\\n\"\n\t}\n\treturn importInsert{\n\t\tLineIndex: lastSingleLineImportIndex + 1,\n\t\tText:      fmt.Sprintf(\"import %s\\n%s\", pkg, suffix),\n\t}\n}\n\nfunc (p *Server) CompletionResolve(ctx context.Context, params *lsp.CompletionItem) (result *lsp.CompletionItem, err error) {\n\tp.Log.Info(\"client -> server: CompletionResolve\")\n\tdefer p.Log.Info(\"client -> server: CompletionResolve end\")\n\treturn p.Target.CompletionResolve(ctx, params)\n}\n\nfunc (p *Server) Declaration(ctx context.Context, params *lsp.DeclarationParams) (result []lsp.Location /* Declaration | DeclarationLink[] | null */, err error) {\n\tp.Log.Info(\"client -> server: Declaration\")\n\tdefer p.Log.Info(\"client -> server: Declaration end\")\n\t// Rewrite the request.\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\t// Call gopls and get the result.\n\tresult, err = p.Target.Declaration(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\tfor i, r := range result {\n\t\tif isTemplGoFile, templURI := convertTemplGoToTemplURI(r.URI); isTemplGoFile {\n\t\t\tresult[i].URI = templURI\n\t\t\tresult[i].Range = p.convertGoRangeToTemplRange(templURI, r.Range)\n\t\t}\n\t}\n\treturn\n}\n\nfunc (p *Server) Definition(ctx context.Context, params *lsp.DefinitionParams) (result []lsp.Location /* Definition | DefinitionLink[] | null */, err error) {\n\tp.Log.Info(\"client -> server: Definition\")\n\tdefer p.Log.Info(\"client -> server: Definition end\")\n\t// Rewrite the request.\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn result, nil\n\t}\n\t// Call gopls and get the result.\n\tresult, err = p.Target.Definition(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\tfor i, r := range result {\n\t\tif isTemplGoFile, templURI := convertTemplGoToTemplURI(r.URI); isTemplGoFile {\n\t\t\tresult[i].URI = templURI\n\t\t\tresult[i].Range = p.convertGoRangeToTemplRange(templURI, r.Range)\n\t\t}\n\t}\n\treturn\n}\n\nfunc (p *Server) DidChange(ctx context.Context, params *lsp.DidChangeTextDocumentParams) (err error) {\n\tp.Log.Info(\"client -> server: DidChange\", slog.Any(\"params\", params))\n\tdefer p.Log.Info(\"client -> server: DidChange end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\tp.Log.Error(\"not a templ file\")\n\t\treturn\n\t}\n\t// Apply content changes to the cached template.\n\td, err := p.TemplSource.Apply(string(templURI), params.ContentChanges)\n\tif err != nil {\n\t\tp.Log.Error(\"error applying changes\", slog.Any(\"error\", err))\n\t\treturn\n\t}\n\t// Update the Go code.\n\tp.Log.Info(\"parsing template\")\n\ttemplate, ok, err := p.parseTemplate(ctx, templURI, d.String())\n\tif err != nil {\n\t\tp.Log.Error(\"parseTemplate failure\", slog.Any(\"error\", err))\n\t}\n\tif !ok {\n\t\tp.Log.Info(\"parseTemplate not OK, but attempting to generate anyway\")\n\t}\n\t// Even if the template isn't parsed successfully, attempt to generate, because we\n\t// need the LSP to have an up-to-date view of completions.\n\tw := new(strings.Builder)\n\t// In future updates, we may pass `WithSkipCodeGeneratedComment` to the generator.\n\t// This will enable a number of actions within gopls that it doesn't currently apply because\n\t// it recognises templ code as being auto-generated.\n\t//\n\t// This change would increase the surface area of gopls that we use, so may surface a number of issues\n\t// if enabled.\n\tgeneratorOutput, err := generator.Generate(template, w)\n\tif err != nil {\n\t\tp.Log.Error(\"generate failure\", slog.Any(\"error\", err))\n\t\treturn\n\t}\n\t// Cache the sourcemap.\n\tp.Log.Info(\"setting cache\", slog.String(\"uri\", string(templURI)))\n\tp.SourceMapCache.Set(string(templURI), generatorOutput.SourceMap)\n\tp.GoSource[string(templURI)] = w.String()\n\n\tif p.NoPreload {\n\t\tparams.TextDocument.URI = templURI\n\t\tif err := p.templDocLazyLoader.Sync(ctx, params); err != nil {\n\t\t\tp.Log.Error(\"lazy loader sync\", slog.Any(\"error\", err))\n\t\t}\n\t}\n\n\t// Change the path.\n\tparams.TextDocument.URI = goURI\n\t// Overwrite all the Go contents.\n\tparams.ContentChanges = []lsp.TextDocumentContentChangeEvent{{\n\t\tText: w.String(),\n\t}}\n\treturn p.Target.DidChange(ctx, params)\n}\n\nfunc (p *Server) DidChangeConfiguration(ctx context.Context, params *lsp.DidChangeConfigurationParams) (err error) {\n\tp.Log.Info(\"client -> server: DidChangeConfiguration\")\n\tdefer p.Log.Info(\"client -> server: DidChangeConfiguration end\")\n\treturn p.Target.DidChangeConfiguration(ctx, params)\n}\n\nfunc (p *Server) DidChangeWatchedFiles(ctx context.Context, params *lsp.DidChangeWatchedFilesParams) (err error) {\n\tp.Log.Info(\"client -> server: DidChangeWatchedFiles\")\n\tdefer p.Log.Info(\"client -> server: DidChangeWatchedFiles end\")\n\treturn p.Target.DidChangeWatchedFiles(ctx, params)\n}\n\nfunc (p *Server) DidChangeWorkspaceFolders(ctx context.Context, params *lsp.DidChangeWorkspaceFoldersParams) (err error) {\n\tp.Log.Info(\"client -> server: DidChangeWorkspaceFolders\")\n\tdefer p.Log.Info(\"client -> server: DidChangeWorkspaceFolders end\")\n\treturn p.Target.DidChangeWorkspaceFolders(ctx, params)\n}\n\nfunc (p *Server) DidClose(ctx context.Context, params *lsp.DidCloseTextDocumentParams) (err error) {\n\tp.Log.Info(\"client -> server: DidClose\")\n\tdefer p.Log.Info(\"client -> server: DidClose end\")\n\n\tif p.NoPreload {\n\t\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\t\tif err != nil {\n\t\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\t\treturn err\n\t\t}\n\n\t\tparams.TextDocument.URI = templURI\n\n\t\treturn p.templDocLazyLoader.Unload(ctx, params)\n\t}\n\n\treturn p.HandleDidClose(ctx, params)\n}\n\nfunc (p *Server) HandleDidClose(ctx context.Context, params *lsp.DidCloseTextDocumentParams) (err error) {\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.DidClose(ctx, params)\n\t}\n\t// Delete the template and sourcemaps from caches.\n\tp.TemplSource.Delete(string(templURI))\n\tp.SourceMapCache.Delete(string(templURI))\n\t// Get gopls to delete the Go file from its cache.\n\tparams.TextDocument.URI = goURI\n\treturn p.Target.DidClose(ctx, params)\n}\n\nfunc (p *Server) DidOpen(ctx context.Context, params *lsp.DidOpenTextDocumentParams) (err error) {\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tp.Log.Info(\"client -> server: DidOpen\", slog.String(\"uri\", string(templURI)))\n\tdefer p.Log.Info(\"client -> server: DidOpen end\")\n\n\tif p.NoPreload {\n\t\tparams.TextDocument.URI = templURI\n\t\treturn p.templDocLazyLoader.Load(ctx, params)\n\t}\n\n\treturn p.HandleDidOpen(ctx, params)\n}\n\nfunc (p *Server) HandleDidOpen(ctx context.Context, params *lsp.DidOpenTextDocumentParams) (err error) {\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.DidOpen(ctx, params)\n\t}\n\t// Cache the template doc.\n\tp.TemplSource.Set(string(templURI), NewDocument(p.Log, params.TextDocument.Text))\n\t// Parse the template.\n\ttemplate, ok, err := p.parseTemplate(ctx, templURI, params.TextDocument.Text)\n\tif err != nil {\n\t\tp.Log.Error(\"parseTemplate failure\", slog.Any(\"error\", err))\n\t}\n\tif !ok {\n\t\tp.Log.Info(\"parsing template did not succeed\", slog.String(\"uri\", string(templURI)))\n\t\treturn nil\n\t}\n\t// Generate the output code and cache the source map and Go contents to use during completion\n\t// requests.\n\tw := new(strings.Builder)\n\tgeneratorOutput, err := generator.Generate(template, w)\n\tif err != nil {\n\t\treturn\n\t}\n\tp.Log.Info(\"setting source map cache contents\", slog.String(\"uri\", string(templURI)))\n\tp.SourceMapCache.Set(string(templURI), generatorOutput.SourceMap)\n\t// Set the Go contents.\n\tparams.TextDocument.Text = w.String()\n\tp.GoSource[string(templURI)] = params.TextDocument.Text\n\t// Change the path.\n\tparams.TextDocument.URI = goURI\n\treturn p.Target.DidOpen(ctx, params)\n}\n\nfunc (p *Server) DidSave(ctx context.Context, params *lsp.DidSaveTextDocumentParams) (err error) {\n\tp.Log.Info(\"client -> server: DidSave\")\n\tdefer p.Log.Info(\"client -> server: DidSave end\")\n\tif isTemplFile, goURI := convertTemplToGoURI(params.TextDocument.URI); isTemplFile {\n\t\tparams.TextDocument.URI = goURI\n\t}\n\treturn p.Target.DidSave(ctx, params)\n}\n\nfunc (p *Server) DocumentColor(ctx context.Context, params *lsp.DocumentColorParams) (result []lsp.ColorInformation, err error) {\n\tp.Log.Info(\"client -> server: DocumentColor\")\n\tdefer p.Log.Info(\"client -> server: DocumentColor end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.DocumentColor(ctx, params)\n\t}\n\tparams.TextDocument.URI = goURI\n\tresult, err = p.Target.DocumentColor(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\tfor i, r := range result {\n\t\tresult[i].Range = p.convertGoRangeToTemplRange(templURI, r.Range)\n\t}\n\treturn\n}\n\nfunc (p *Server) DocumentHighlight(ctx context.Context, params *lsp.DocumentHighlightParams) (result []lsp.DocumentHighlight, err error) {\n\tp.Log.Info(\"client -> server: DocumentHighlight\")\n\tdefer p.Log.Info(\"client -> server: DocumentHighlight end\")\n\treturn\n}\n\nfunc (p *Server) DocumentLink(ctx context.Context, params *lsp.DocumentLinkParams) (result []lsp.DocumentLink, err error) {\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tp.Log.Info(\"client -> server: DocumentLink\", slog.String(\"uri\", string(templURI)))\n\tdefer p.Log.Info(\"client -> server: DocumentLink end\")\n\treturn\n}\n\nfunc (p *Server) DocumentLinkResolve(ctx context.Context, params *lsp.DocumentLink) (result *lsp.DocumentLink, err error) {\n\tp.Log.Info(\"client -> server: DocumentLinkResolve\")\n\tdefer p.Log.Info(\"client -> server: DocumentLinkResolve end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.Target))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.Target)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.DocumentLinkResolve(ctx, params)\n\t}\n\tparams.Target = goURI\n\tvar ok bool\n\tif params.Range, ok = p.convertTemplRangeToGoRange(templURI, params.Range); !ok {\n\t\treturn\n\t}\n\t// Rewrite the result.\n\tresult, err = p.Target.DocumentLinkResolve(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\tresult.Target = templURI\n\tresult.Range = p.convertGoRangeToTemplRange(templURI, result.Range)\n\treturn\n}\n\nfunc (p *Server) DocumentSymbol(ctx context.Context, params *lsp.DocumentSymbolParams) (result []lsp.SymbolInformationOrDocumentSymbol, err error) {\n\tp.Log.Info(\"client -> server: DocumentSymbol\")\n\tdefer p.Log.Info(\"client -> server: DocumentSymbol end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tisTemplFile, goURI := convertTemplToGoURI(templURI)\n\tif !isTemplFile {\n\t\treturn p.Target.DocumentSymbol(ctx, params)\n\t}\n\tparams.TextDocument.URI = goURI\n\tsymbols, err := p.Target.DocumentSymbol(ctx, params)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, s := range symbols {\n\t\tif s.DocumentSymbol != nil {\n\t\t\tp.convertSymbolRange(templURI, s.DocumentSymbol)\n\t\t\tresult = append(result, s)\n\t\t}\n\t\tif s.SymbolInformation != nil {\n\t\t\ts.SymbolInformation.Location.URI = templURI\n\t\t\ts.SymbolInformation.Location.Range = p.convertGoRangeToTemplRange(templURI, s.SymbolInformation.Location.Range)\n\t\t\tresult = append(result, s)\n\t\t}\n\t}\n\n\treturn result, err\n}\n\nfunc (p *Server) convertSymbolRange(templURI lsp.DocumentURI, s *lsp.DocumentSymbol) {\n\tsourceMap, ok := p.SourceMapCache.Get(string(templURI))\n\tif !ok {\n\t\tp.Log.Warn(\"go->templ: sourcemap not found in cache\")\n\t\treturn\n\t}\n\tsrc, ok := sourceMap.SymbolSourceRangeFromTarget(s.Range.Start.Line, s.Range.Start.Character)\n\tif !ok {\n\t\tp.Log.Warn(\"go->templ: symbol range not found\", slog.Any(\"symbol\", s), slog.Any(\"choices\", sourceMap.TargetSymbolRangeToSource))\n\t\treturn\n\t}\n\ts.Range = lsp.Range{\n\t\tStart: lsp.Position{\n\t\t\tLine:      uint32(src.From.Line),\n\t\t\tCharacter: uint32(src.From.Col),\n\t\t},\n\t\tEnd: lsp.Position{\n\t\t\tLine:      uint32(src.To.Line),\n\t\t\tCharacter: uint32(src.To.Col),\n\t\t},\n\t}\n\t// Within the symbol, we can select sub-sections.\n\t// These are Go expressions, in the standard source map.\n\ts.SelectionRange = p.convertGoRangeToTemplRange(templURI, s.SelectionRange)\n\tfor i := range s.Children {\n\t\tp.convertSymbolRange(templURI, &s.Children[i])\n\t\tif !isRangeWithin(s.Range, s.Children[i].Range) {\n\t\t\tp.Log.Error(\"child symbol range not within parent range\", slog.Any(\"symbol\", s.Children[i]), slog.Int(\"index\", i))\n\t\t}\n\t}\n\tif !isRangeWithin(s.Range, s.SelectionRange) {\n\t\tp.Log.Error(\"selection range not within range\", slog.Any(\"symbol\", s))\n\t}\n}\n\nfunc isRangeWithin(parent, child lsp.Range) bool {\n\tif child.Start.Line < parent.Start.Line || child.End.Line > parent.End.Line {\n\t\treturn false\n\t}\n\tif child.Start.Line == parent.Start.Line && child.Start.Character < parent.Start.Character {\n\t\treturn false\n\t}\n\tif child.End.Line == parent.End.Line && child.End.Character > parent.End.Character {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (p *Server) ExecuteCommand(ctx context.Context, params *lsp.ExecuteCommandParams) (result any, err error) {\n\tp.Log.Info(\"client -> server: ExecuteCommand\")\n\tdefer p.Log.Info(\"client -> server: ExecuteCommand end\")\n\treturn p.Target.ExecuteCommand(ctx, params)\n}\n\nfunc (p *Server) FoldingRanges(ctx context.Context, params *lsp.FoldingRangeParams) (result []lsp.FoldingRange, err error) {\n\tp.Log.Info(\"client -> server: FoldingRanges\")\n\tdefer p.Log.Info(\"client -> server: FoldingRanges end\")\n\t// There are no folding ranges in templ files.\n\t// return p.Target.FoldingRanges(ctx, params)\n\treturn []lsp.FoldingRange{}, nil\n}\n\nfunc (p *Server) Formatting(ctx context.Context, params *lsp.DocumentFormattingParams) (result []lsp.TextEdit, err error) {\n\tp.Log.Info(\"client -> server: Formatting\")\n\tdefer p.Log.Info(\"client -> server: Formatting end\")\n\t// Format the current document.\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\td, _ := p.TemplSource.Get(string(templURI))\n\ttemplate, ok, err := p.parseTemplate(ctx, templURI, d.String())\n\tif err != nil {\n\t\tp.Log.Error(\"parseTemplate failure\", slog.Any(\"error\", err))\n\t\treturn\n\t}\n\tif !ok {\n\t\treturn\n\t}\n\tp.Log.Info(\"attempting to organise imports\", slog.String(\"uri\", template.Filepath))\n\ttemplate, err = imports.Process(template)\n\tif err != nil {\n\t\tp.Log.Error(\"organise imports failure\", slog.Any(\"error\", err))\n\t\treturn\n\t}\n\tw := new(strings.Builder)\n\terr = template.Write(w)\n\tif err != nil {\n\t\tp.Log.Error(\"handleFormatting: faled to write template\", slog.Any(\"error\", err))\n\t\treturn\n\t}\n\t// Replace everything.\n\tresult = append(result, lsp.TextEdit{\n\t\tRange: lsp.Range{\n\t\t\tStart: lsp.Position{},\n\t\t\tEnd:   lsp.Position{Line: uint32(len(d.Lines)), Character: 0},\n\t\t},\n\t\tNewText: w.String(),\n\t})\n\td.Replace(w.String())\n\treturn\n}\n\nfunc (p *Server) Hover(ctx context.Context, params *lsp.HoverParams) (result *lsp.Hover, err error) {\n\tp.Log.Info(\"client -> server: Hover\")\n\tdefer p.Log.Info(\"client -> server: Hover end\")\n\t// Rewrite the request.\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\t// Call gopls.\n\tresult, err = p.Target.Hover(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\t// Rewrite the response.\n\tif result != nil && result.Range != nil {\n\t\tp.Log.Info(\"hover: result returned\")\n\t\tr := p.convertGoRangeToTemplRange(templURI, *result.Range)\n\t\tp.Log.Info(\"hover: setting range\")\n\t\tresult.Range = &r\n\t}\n\treturn\n}\n\nfunc (p *Server) Implementation(ctx context.Context, params *lsp.ImplementationParams) (result []lsp.Location, err error) {\n\tp.Log.Info(\"client -> server: Implementation\")\n\tdefer p.Log.Info(\"client -> server: Implementation end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\t// Rewrite the request.\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\tresult, err = p.Target.Implementation(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\t// Rewrite the response.\n\tfor i, r := range result {\n\t\tr.URI = templURI\n\t\tr.Range = p.convertGoRangeToTemplRange(templURI, r.Range)\n\t\tresult[i] = r\n\t}\n\treturn\n}\n\nfunc (p *Server) OnTypeFormatting(ctx context.Context, params *lsp.DocumentOnTypeFormattingParams) (result []lsp.TextEdit, err error) {\n\tp.Log.Info(\"client -> server: OnTypeFormatting\")\n\tdefer p.Log.Info(\"client -> server: OnTypeFormatting end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\t// Rewrite the request.\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\t// Get the response.\n\tresult, err = p.Target.OnTypeFormatting(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\t// Rewrite the response.\n\tfor i, r := range result {\n\t\tr.Range = p.convertGoRangeToTemplRange(templURI, r.Range)\n\t\tresult[i] = r\n\t}\n\treturn\n}\n\nfunc (p *Server) PrepareRename(ctx context.Context, params *lsp.PrepareRenameParams) (result *lsp.Range, err error) {\n\tp.Log.Info(\"client -> server: PrepareRename\")\n\tdefer p.Log.Info(\"client -> server: PrepareRename end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\t// Rewrite the request.\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\t// Get the response.\n\tresult, err = p.Target.PrepareRename(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\tif result == nil {\n\t\treturn\n\t}\n\t// Rewrite the response.\n\toutput := p.convertGoRangeToTemplRange(templURI, *result)\n\treturn &output, nil\n}\n\nfunc (p *Server) RangeFormatting(ctx context.Context, params *lsp.DocumentRangeFormattingParams) (result []lsp.TextEdit, err error) {\n\tp.Log.Info(\"client -> server: RangeFormatting\")\n\tdefer p.Log.Info(\"client -> server: RangeFormatting end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\t// Rewrite the request.\n\tvar isTemplURI bool\n\tisTemplURI, params.TextDocument.URI = convertTemplToGoURI(templURI)\n\tif !isTemplURI {\n\t\terr = fmt.Errorf(\"not a templ file\")\n\t\treturn\n\t}\n\t// Call gopls.\n\tresult, err = p.Target.RangeFormatting(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\t// Rewrite the response.\n\tfor i, r := range result {\n\t\tr.Range = p.convertGoRangeToTemplRange(templURI, r.Range)\n\t\tresult[i] = r\n\t}\n\treturn result, err\n}\n\nfunc (p *Server) References(ctx context.Context, params *lsp.ReferenceParams) (result []lsp.Location, err error) {\n\tp.Log.Info(\"client -> server: References\")\n\tdefer p.Log.Info(\"client -> server: References end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\t// Rewrite the request.\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\t// Call gopls.\n\tresult, err = p.Target.References(ctx, params)\n\tif err != nil {\n\t\treturn\n\t}\n\t// Rewrite the response.\n\tfor i, r := range result {\n\t\tisTemplURI, templURI := convertTemplGoToTemplURI(r.URI)\n\t\tif isTemplURI {\n\t\t\tp.Log.Info(fmt.Sprintf(\"references-%d - range conversion for %s\", i, r.URI))\n\t\t\tr.URI, r.Range = templURI, p.convertGoRangeToTemplRange(templURI, r.Range)\n\t\t}\n\t\tp.Log.Info(fmt.Sprintf(\"references-%d: %+v\", i, r))\n\t\tresult[i] = r\n\t}\n\treturn result, err\n}\n\nfunc (p *Server) Rename(ctx context.Context, params *lsp.RenameParams) (result *lsp.WorkspaceEdit, err error) {\n\tp.Log.Info(\"client -> server: Rename\")\n\tdefer p.Log.Info(\"client -> server: Rename end\")\n\treturn p.Target.Rename(ctx, params)\n}\n\nfunc (p *Server) SignatureHelp(ctx context.Context, params *lsp.SignatureHelpParams) (result *lsp.SignatureHelp, err error) {\n\tp.Log.Info(\"client -> server: SignatureHelp\")\n\tdefer p.Log.Info(\"client -> server: SignatureHelp end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\treturn p.Target.SignatureHelp(ctx, params)\n}\n\nfunc (p *Server) Symbols(ctx context.Context, params *lsp.WorkspaceSymbolParams) (result []lsp.SymbolInformation, err error) {\n\tp.Log.Info(\"client -> server: Symbols\")\n\tdefer p.Log.Info(\"client -> server: Symbols end\")\n\treturn p.Target.Symbols(ctx, params)\n}\n\nfunc (p *Server) TypeDefinition(ctx context.Context, params *lsp.TypeDefinitionParams) (result []lsp.Location, err error) {\n\tp.Log.Info(\"client -> server: TypeDefinition\")\n\tdefer p.Log.Info(\"client -> server: TypeDefinition end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\treturn p.Target.TypeDefinition(ctx, params)\n}\n\nfunc (p *Server) WillSave(ctx context.Context, params *lsp.WillSaveTextDocumentParams) (err error) {\n\tp.Log.Info(\"client -> server: WillSave\")\n\tdefer p.Log.Info(\"client -> server: WillSave end\")\n\tvar ok bool\n\tok, params.TextDocument.URI = convertTemplToGoURI(params.TextDocument.URI)\n\tif !ok {\n\t\tp.Log.Error(\"not a templ file\")\n\t\treturn nil\n\t}\n\treturn p.Target.WillSave(ctx, params)\n}\n\nfunc (p *Server) WillSaveWaitUntil(ctx context.Context, params *lsp.WillSaveTextDocumentParams) (result []lsp.TextEdit, err error) {\n\tp.Log.Info(\"client -> server: WillSaveWaitUntil\")\n\tdefer p.Log.Info(\"client -> server: WillSaveWaitUntil end\")\n\treturn p.Target.WillSaveWaitUntil(ctx, params)\n}\n\nfunc (p *Server) ShowDocument(ctx context.Context, params *lsp.ShowDocumentParams) (result *lsp.ShowDocumentResult, err error) {\n\tp.Log.Info(\"client -> server: ShowDocument\")\n\tdefer p.Log.Info(\"client -> server: ShowDocument end\")\n\treturn p.Target.ShowDocument(ctx, params)\n}\n\nfunc (p *Server) WillCreateFiles(ctx context.Context, params *lsp.CreateFilesParams) (result *lsp.WorkspaceEdit, err error) {\n\tp.Log.Info(\"client -> server: WillCreateFiles\")\n\tdefer p.Log.Info(\"client -> server: WillCreateFiles end\")\n\treturn p.Target.WillCreateFiles(ctx, params)\n}\n\nfunc (p *Server) DidCreateFiles(ctx context.Context, params *lsp.CreateFilesParams) (err error) {\n\tp.Log.Info(\"client -> server: DidCreateFiles\")\n\tdefer p.Log.Info(\"client -> server: DidCreateFiles end\")\n\treturn p.Target.DidCreateFiles(ctx, params)\n}\n\nfunc (p *Server) WillRenameFiles(ctx context.Context, params *lsp.RenameFilesParams) (result *lsp.WorkspaceEdit, err error) {\n\tp.Log.Info(\"client -> server: WillRenameFiles\")\n\tdefer p.Log.Info(\"client -> server: WillRenameFiles end\")\n\treturn p.Target.WillRenameFiles(ctx, params)\n}\n\nfunc (p *Server) DidRenameFiles(ctx context.Context, params *lsp.RenameFilesParams) (err error) {\n\tp.Log.Info(\"client -> server: DidRenameFiles\")\n\tdefer p.Log.Info(\"client -> server: DidRenameFiles end\")\n\treturn p.Target.DidRenameFiles(ctx, params)\n}\n\nfunc (p *Server) WillDeleteFiles(ctx context.Context, params *lsp.DeleteFilesParams) (result *lsp.WorkspaceEdit, err error) {\n\tp.Log.Info(\"client -> server: WillDeleteFiles\")\n\tdefer p.Log.Info(\"client -> server: WillDeleteFiles end\")\n\treturn p.Target.WillDeleteFiles(ctx, params)\n}\n\nfunc (p *Server) DidDeleteFiles(ctx context.Context, params *lsp.DeleteFilesParams) (err error) {\n\tp.Log.Info(\"client -> server: DidDeleteFiles\")\n\tdefer p.Log.Info(\"client -> server: DidDeleteFiles end\")\n\treturn p.Target.DidDeleteFiles(ctx, params)\n}\n\nfunc (p *Server) CodeLensRefresh(ctx context.Context) (err error) {\n\tp.Log.Info(\"client -> server: CodeLensRefresh\")\n\tdefer p.Log.Info(\"client -> server: CodeLensRefresh end\")\n\treturn p.Target.CodeLensRefresh(ctx)\n}\n\nfunc (p *Server) PrepareCallHierarchy(ctx context.Context, params *lsp.CallHierarchyPrepareParams) (result []lsp.CallHierarchyItem, err error) {\n\tp.Log.Info(\"client -> server: PrepareCallHierarchy\")\n\tdefer p.Log.Info(\"client -> server: PrepareCallHierarchy end\")\n\treturn p.Target.PrepareCallHierarchy(ctx, params)\n}\n\nfunc (p *Server) IncomingCalls(ctx context.Context, params *lsp.CallHierarchyIncomingCallsParams) (result []lsp.CallHierarchyIncomingCall, err error) {\n\tp.Log.Info(\"client -> server: IncomingCalls\")\n\tdefer p.Log.Info(\"client -> server: IncomingCalls end\")\n\treturn p.Target.IncomingCalls(ctx, params)\n}\n\nfunc (p *Server) OutgoingCalls(ctx context.Context, params *lsp.CallHierarchyOutgoingCallsParams) (result []lsp.CallHierarchyOutgoingCall, err error) {\n\tp.Log.Info(\"client -> server: OutgoingCalls\")\n\tdefer p.Log.Info(\"client -> server: OutgoingCalls end\")\n\treturn p.Target.OutgoingCalls(ctx, params)\n}\n\nfunc (p *Server) SemanticTokensFull(ctx context.Context, params *lsp.SemanticTokensParams) (result *lsp.SemanticTokens, err error) {\n\tp.Log.Info(\"client -> server: SemanticTokensFull\")\n\tdefer p.Log.Info(\"client -> server: SemanticTokensFull end\")\n\tisTemplFile, goURI := convertTemplToGoURI(params.TextDocument.URI)\n\tif !isTemplFile {\n\t\treturn nil, nil\n\t}\n\tparams.TextDocument.URI = goURI\n\treturn p.Target.SemanticTokensFull(ctx, params)\n}\n\nfunc (p *Server) SemanticTokensFullDelta(ctx context.Context, params *lsp.SemanticTokensDeltaParams) (result any /* SemanticTokens | SemanticTokensDelta */, err error) {\n\tp.Log.Info(\"client -> server: SemanticTokensFullDelta\")\n\tdefer p.Log.Info(\"client -> server: SemanticTokensFullDelta end\")\n\tisTemplFile, goURI := convertTemplToGoURI(params.TextDocument.URI)\n\tif !isTemplFile {\n\t\treturn nil, nil\n\t}\n\tparams.TextDocument.URI = goURI\n\treturn p.Target.SemanticTokensFullDelta(ctx, params)\n}\n\nfunc (p *Server) SemanticTokensRange(ctx context.Context, params *lsp.SemanticTokensRangeParams) (result *lsp.SemanticTokens, err error) {\n\tp.Log.Info(\"client -> server: SemanticTokensRange\")\n\tdefer p.Log.Info(\"client -> server: SemanticTokensRange end\")\n\tisTemplFile, goURI := convertTemplToGoURI(params.TextDocument.URI)\n\tif !isTemplFile {\n\t\treturn nil, nil\n\t}\n\tparams.TextDocument.URI = goURI\n\treturn p.Target.SemanticTokensRange(ctx, params)\n}\n\nfunc (p *Server) SemanticTokensRefresh(ctx context.Context) (err error) {\n\tp.Log.Info(\"client -> server: SemanticTokensRefresh\")\n\tdefer p.Log.Info(\"client -> server: SemanticTokensRefresh end\")\n\treturn p.Target.SemanticTokensRefresh(ctx)\n}\n\nfunc (p *Server) LinkedEditingRange(ctx context.Context, params *lsp.LinkedEditingRangeParams) (result *lsp.LinkedEditingRanges, err error) {\n\tp.Log.Info(\"client -> server: LinkedEditingRange\")\n\tdefer p.Log.Info(\"client -> server: LinkedEditingRange end\")\n\treturn p.Target.LinkedEditingRange(ctx, params)\n}\n\nfunc (p *Server) Moniker(ctx context.Context, params *lsp.MonikerParams) (result []lsp.Moniker, err error) {\n\tp.Log.Info(\"client -> server: Moniker\")\n\tdefer p.Log.Info(\"client -> server: Moniker end\")\n\ttemplURI, err := uri.ParseDocumentURI(string(params.TextDocument.URI))\n\tif err != nil {\n\t\tp.Log.Error(\"invalid uri\", slog.String(\"uri\", string(params.TextDocument.URI)))\n\t\treturn\n\t}\n\tvar ok bool\n\tok, params.TextDocument.URI, params.Position = p.updatePosition(templURI, params.Position)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\treturn p.Target.Moniker(ctx, params)\n}\n\nfunc (p *Server) Request(ctx context.Context, method string, params any) (result any, err error) {\n\tp.Log.Info(\"client -> server: Request\")\n\tdefer p.Log.Info(\"client -> server: Request end\")\n\treturn p.Target.Request(ctx, method, params)\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/snippets.go",
    "content": "package proxy\n\nimport lsp \"github.com/a-h/templ/lsp/protocol\"\n\nvar htmlSnippets = []lsp.CompletionItem{\n\t{\n\t\tLabel: \"<?>\",\n\t\tInsertText: `${1}>\n\t${0}\n</${1}>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"a\",\n\t\tInsertText:       `a href=\"${1:}\">${2:}</a>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"button\",\n\t\tInsertText:       `button type=\"button\" ${1:}>${2:}</button>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel: \"div\",\n\t\tInsertText: `div>\n\t${0}\n</div>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel: \"p\",\n\t\tInsertText: `p>\n    ${0}\n</p>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel: \"head\",\n\t\tInsertText: `head>\n    ${0}\n</head>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel: \"body\",\n\t\tInsertText: `body>\n    ${0}\n</body>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"title\",\n\t\tInsertText:       `title>${0}</title>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"h1\",\n\t\tInsertText:       `h1>${0}</h1>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"h2\",\n\t\tInsertText:       `h2>${0}</h2>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"h3\",\n\t\tInsertText:       `h3>${0}</h3>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"h4\",\n\t\tInsertText:       `h4>${0}</h4>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"h5\",\n\t\tInsertText:       `h5>${0}</h5>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n\t{\n\t\tLabel:            \"h6\",\n\t\tInsertText:       `h6>${0}</h6>`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n}\n\nvar snippet = []lsp.CompletionItem{\n\t{\n\t\tLabel: \"templ\",\n\t\tInsertText: `templ ${2:TemplateName}() {\n\t${0}\n}`,\n\t\tKind:             lsp.CompletionItemKind(lsp.CompletionItemKindSnippet),\n\t\tInsertTextFormat: lsp.InsertTextFormatSnippet,\n\t},\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/sourcemapcache.go",
    "content": "package proxy\n\nimport (\n\t\"slices\"\n\t\"sync\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\n// NewSourceMapCache creates a cache of .templ file URIs to the source map.\nfunc NewSourceMapCache() *SourceMapCache {\n\treturn &SourceMapCache{\n\t\tm:              new(sync.Mutex),\n\t\turiToSourceMap: make(map[string]*parser.SourceMap),\n\t}\n}\n\n// SourceMapCache is a cache of .templ file URIs to the source map.\ntype SourceMapCache struct {\n\tm              *sync.Mutex\n\turiToSourceMap map[string]*parser.SourceMap\n}\n\nfunc (fc *SourceMapCache) Set(uri string, m *parser.SourceMap) {\n\tfc.m.Lock()\n\tdefer fc.m.Unlock()\n\n\tif m == nil {\n\t\tdelete(fc.uriToSourceMap, uri)\n\t\treturn\n\t}\n\n\tfc.uriToSourceMap[uri] = m\n}\n\nfunc (fc *SourceMapCache) Get(uri string) (m *parser.SourceMap, ok bool) {\n\tfc.m.Lock()\n\tdefer fc.m.Unlock()\n\tm, ok = fc.uriToSourceMap[uri]\n\treturn\n}\n\nfunc (fc *SourceMapCache) Delete(uri string) {\n\tfc.m.Lock()\n\tdefer fc.m.Unlock()\n\tdelete(fc.uriToSourceMap, uri)\n}\n\nfunc (fc *SourceMapCache) URIs() (uris []string) {\n\tfc.m.Lock()\n\tdefer fc.m.Unlock()\n\turis = make([]string, len(fc.uriToSourceMap))\n\tvar i int\n\tfor k := range fc.uriToSourceMap {\n\t\turis[i] = k\n\t\ti++\n\t}\n\tslices.Sort(uris)\n\treturn uris\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/proxy/sourcemapcache_test.go",
    "content": "package proxy\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestSourceMapCache(t *testing.T) {\n\tt.Run(\"can list URIs\", func(t *testing.T) {\n\t\tsmc := NewSourceMapCache()\n\t\tsmc.Set(\"d\", parser.NewSourceMap())\n\t\tsmc.Set(\"c\", parser.NewSourceMap())\n\n\t\tactual := smc.URIs()\n\t\texpected := []string{\"c\", \"d\"}\n\t\tif diff := cmp.Diff(expected, actual); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"can delete entries\", func(t *testing.T) {\n\t\tsmc := NewSourceMapCache()\n\t\tsmc.Set(\"a\", parser.NewSourceMap())\n\t\tsmc.Set(\"b\", parser.NewSourceMap())\n\n\t\tsmc.Delete(\"a\")\n\t\tactual := smc.URIs()\n\t\texpected := []string{\"b\"}\n\t\tif diff := cmp.Diff(expected, actual); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"nil source maps\", func(t *testing.T) {\n\t\tt.Run(\"are not cached\", func(t *testing.T) {\n\t\t\tsmc := NewSourceMapCache()\n\n\t\t\tvar sm *parser.SourceMap\n\t\t\tsmc.Set(\"test\", sm)\n\n\t\t\tif _, ok := smc.Get(\"test\"); ok {\n\t\t\t\tt.Error(\"expected nil source map to not be cached\")\n\t\t\t}\n\t\t})\n\t\tt.Run(\"delete existing cache entries\", func(t *testing.T) {\n\t\t\tsmc := NewSourceMapCache()\n\n\t\t\tsm := parser.NewSourceMap()\n\t\t\tsmc.Set(\"test\", sm)\n\t\t\tif _, ok := smc.Get(\"test\"); !ok {\n\t\t\t\tt.Error(\"expected non-nil source map to be cached\")\n\t\t\t}\n\n\t\t\tsm = nil\n\t\t\tsmc.Set(\"test\", sm)\n\t\t\tif existing, ok := smc.Get(\"test\"); ok || existing != nil {\n\t\t\t\tt.Error(\"expected nil source map set to clear existing cache entry\")\n\t\t\t}\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "cmd/templ/lspcmd/stdrwc.go",
    "content": "package lspcmd\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"log/slog\"\n)\n\n// stdrwc (standard read/write closer) reads from stdin, and writes to stdout.\nfunc newStdRwc(log *slog.Logger, name string, w io.Writer, r io.Reader) stdrwc {\n\treturn stdrwc{\n\t\tlog:  log,\n\t\tname: name,\n\t\tw:    w,\n\t\tr:    r,\n\t}\n}\n\ntype stdrwc struct {\n\tlog  *slog.Logger\n\tname string\n\tw    io.Writer\n\tr    io.Reader\n}\n\nfunc (s stdrwc) Read(p []byte) (int, error) {\n\treturn s.r.Read(p)\n}\n\nfunc (s stdrwc) Write(p []byte) (int, error) {\n\treturn s.w.Write(p)\n}\n\nfunc (s stdrwc) Close() error {\n\ts.log.Info(\"rwc: closing\", slog.String(\"name\", s.name))\n\tvar errs []error\n\tif closer, isCloser := s.r.(io.Closer); isCloser {\n\t\tif err := closer.Close(); err != nil {\n\t\t\ts.log.Error(\"rwc: error closing reader\", slog.String(\"name\", s.name), slog.Any(\"error\", err))\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\tif closer, isCloser := s.w.(io.Closer); isCloser {\n\t\tif err := closer.Close(); err != nil {\n\t\t\ts.log.Error(\"rwc: error closing writer\", slog.String(\"name\", s.name), slog.Any(\"error\", err))\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\treturn errors.Join(errs...)\n}\n"
  },
  {
    "path": "cmd/templ/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/signal\"\n\t\"runtime\"\n\t\"syscall\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/cmd/templ/fmtcmd\"\n\t\"github.com/a-h/templ/cmd/templ/generatecmd\"\n\t\"github.com/a-h/templ/cmd/templ/infocmd\"\n\t\"github.com/a-h/templ/cmd/templ/lspcmd\"\n\t\"github.com/a-h/templ/cmd/templ/sloghandler\"\n\t\"github.com/fatih/color\"\n)\n\nfunc main() {\n\tcode := run(os.Stdin, os.Stdout, os.Stderr, os.Args)\n\tif code != 0 {\n\t\tos.Exit(code)\n\t}\n}\n\nconst usageText = `usage: templ <command> [<args>...]\n\ntempl - build HTML UIs with Go\n\nSee docs at https://templ.guide\n\ncommands:\n  generate   Generates Go code from templ files\n  fmt        Formats templ files\n  lsp        Starts a language server for templ files\n  info       Displays information about the templ environment\n  version    Prints the version\n`\n\nfunc run(stdin io.Reader, stdout, stderr io.Writer, args []string) (code int) {\n\tif len(args) < 2 {\n\t\t_, _ = fmt.Fprint(stderr, usageText)\n\t\treturn 64 // EX_USAGE\n\t}\n\tswitch args[1] {\n\tcase \"info\":\n\t\treturn infoCmd(stdout, stderr, args[2:])\n\tcase \"generate\":\n\t\treturn generateCmd(stdout, stderr, args[2:])\n\tcase \"fmt\":\n\t\treturn fmtCmd(stdin, stdout, stderr, args[2:])\n\tcase \"lsp\":\n\t\treturn lspCmd(stdin, stdout, stderr, args[2:])\n\tcase \"version\", \"--version\":\n\t\t_, _ = fmt.Fprintln(stdout, templ.Version())\n\t\treturn 0\n\tcase \"help\", \"-help\", \"--help\", \"-h\":\n\t\t_, _ = fmt.Fprint(stdout, usageText)\n\t\treturn 0\n\t}\n\t_, _ = fmt.Fprint(stderr, usageText)\n\treturn 64 // EX_USAGE\n}\n\nconst infoUsageText = `usage: templ info [<args>...]\n\nDisplays information about the templ environment.\n\nArgs:\n  -json\n    Output information in JSON format to stdout. (default false)\n  -v\n    Set log verbosity level to \"debug\". (default \"info\")\n  -log-level\n    Set log verbosity level. (default \"info\", options: \"debug\", \"info\", \"warn\", \"error\")\n  -help\n    Print help and exit.\n`\n\nfunc infoCmd(stdout, stderr io.Writer, args []string) (code int) {\n\tcmd := flag.NewFlagSet(\"diagnose\", flag.ExitOnError)\n\tjsonFlag := cmd.Bool(\"json\", false, \"\")\n\tverboseFlag := cmd.Bool(\"v\", false, \"\")\n\tlogLevelFlag := cmd.String(\"log-level\", \"info\", \"\")\n\thelpFlag := cmd.Bool(\"help\", false, \"\")\n\terr := cmd.Parse(args)\n\tif err != nil {\n\t\t_, _ = fmt.Fprint(stderr, infoUsageText)\n\t\treturn 64 // EX_USAGE\n\t}\n\tif *helpFlag {\n\t\t_, _ = fmt.Fprint(stdout, infoUsageText)\n\t\treturn\n\t}\n\n\tlog := sloghandler.NewLogger(*logLevelFlag, *verboseFlag, stderr)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tsignalChan := make(chan os.Signal, 1)\n\tsignal.Notify(signalChan, os.Interrupt)\n\tgo func() {\n\t\t<-signalChan\n\t\t_, _ = fmt.Fprintln(stderr, \"Stopping...\")\n\t\tcancel()\n\t}()\n\n\terr = infocmd.Run(ctx, log, stdout, infocmd.Arguments{\n\t\tJSON: *jsonFlag,\n\t})\n\tif err != nil {\n\t\t_, _ = color.New(color.FgRed).Fprint(stderr, \"(✗) \")\n\t\t_, _ = fmt.Fprintln(stderr, \"Command failed: \"+err.Error())\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc generateCmd(stdout, stderr io.Writer, args []string) (code int) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tsignalChan := make(chan os.Signal, 1)\n\tsignal.Notify(signalChan, os.Interrupt, syscall.SIGTERM)\n\tgo func() {\n\t\t<-signalChan\n\t\t_, _ = fmt.Fprintln(stderr, \"Stopping...\")\n\t\tcancel()\n\t}()\n\n\terr := generatecmd.Run(ctx, stdout, stderr, args)\n\tif err != nil {\n\t\t_, _ = color.New(color.FgRed).Fprint(stderr, \"(✗) \")\n\t\t_, _ = fmt.Fprintln(stderr, \"Command failed: \"+err.Error())\n\t\texitCode := 1\n\t\tif e, ok := err.(ErrorCode); ok {\n\t\t\texitCode = e.Code()\n\t\t}\n\t\treturn exitCode\n\t}\n\treturn 0\n}\n\ntype ErrorCode interface {\n\terror\n\tCode() int\n}\n\nconst fmtUsageText = `usage: templ fmt [<args> ...]\n\nFormat all files in directory:\n\n  templ fmt .\n\nFormat stdin to stdout:\n\n  templ fmt < header.templ\n\nFormat file or directory to stdout:\n\n  templ fmt -stdout FILE\n\nArgs:\n  -stdout\n    Prints to stdout instead of in-place format\n  -stdin-filepath\n    Provides the formatter with filepath context when using -stdout.\n    Required for organising imports.\n  -v\n    Set log verbosity level to \"debug\". (default \"info\")\n  -log-level\n    Set log verbosity level. (default \"info\", options: \"debug\", \"info\", \"warn\", \"error\")\n  -w\n    Number of workers to use when formatting code. (default runtime.NumCPUs).\n  -prettier-command\n    Set the command to use for formatting HTML, CSS, and JS blocks. Default is \"prettier --stdin-filepath $TEMPL_PRETTIER_FILENAME\".\n  -prettier-required\n    Set to true to return an error the prettier command is not available. Default is false.\n  -fail\n    Fails with exit code 1 if files are changed. (e.g. in CI)\n  -help\n    Print help and exit.\n`\n\nfunc fmtCmd(stdin io.Reader, stdout, stderr io.Writer, args []string) (code int) {\n\tcmd := flag.NewFlagSet(\"fmt\", flag.ExitOnError)\n\thelpFlag := cmd.Bool(\"help\", false, \"\")\n\tworkerCountFlag := cmd.Int(\"w\", runtime.NumCPU(), \"\")\n\tverboseFlag := cmd.Bool(\"v\", false, \"\")\n\tlogLevelFlag := cmd.String(\"log-level\", \"info\", \"\")\n\tfailIfChanged := cmd.Bool(\"fail\", false, \"\")\n\tprettierCommand := cmd.String(\"prettier-command\", \"\", \"\")\n\tprettierRequired := cmd.Bool(\"prettier-required\", false, \"\")\n\tstdoutFlag := cmd.Bool(\"stdout\", false, \"\")\n\tstdinFilepath := cmd.String(\"stdin-filepath\", \"\", \"\")\n\terr := cmd.Parse(args)\n\tif err != nil {\n\t\t_, _ = fmt.Fprint(stderr, fmtUsageText)\n\t\treturn 64 // EX_USAGE\n\t}\n\tif *helpFlag {\n\t\t_, _ = fmt.Fprint(stdout, fmtUsageText)\n\t\treturn\n\t}\n\n\tlog := sloghandler.NewLogger(*logLevelFlag, *verboseFlag, stderr)\n\n\terr = fmtcmd.Run(log, stdin, stdout, fmtcmd.Arguments{\n\t\tToStdout:         *stdoutFlag,\n\t\tFiles:            cmd.Args(),\n\t\tWorkerCount:      *workerCountFlag,\n\t\tStdinFilepath:    *stdinFilepath,\n\t\tFailIfChanged:    *failIfChanged,\n\t\tPrettierCommand:  *prettierCommand,\n\t\tPrettierRequired: *prettierRequired,\n\t})\n\tif err != nil {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nconst lspUsageText = `usage: templ lsp [<args> ...]\n\nStarts a language server for templ.\n\nArgs:\n  -log string\n    The file to log templ LSP output to, or leave empty to disable logging.\n  -goplsLog string\n    The file to log gopls output, or leave empty to disable logging.\n  -goplsRPCTrace\n    Set gopls to log input and output messages.\n  -gopls-remote\n    Specify remote gopls instance to connect to.\n  -help\n    Print help and exit.\n  -pprof\n    Enable pprof web server (default address is localhost:9999)\n  -http string\n    Enable http debug server by setting a listen address (e.g. localhost:7474)\n  -no-preload\n    Disable preloading of templ files on server startup and use custom GOPACKAGESDRIVER for lazy loading (useful for large monorepos). GOPACKAGESDRIVER environment variable must be set.\n`\n\nfunc lspCmd(stdin io.Reader, stdout, stderr io.Writer, args []string) (code int) {\n\tcmd := flag.NewFlagSet(\"lsp\", flag.ExitOnError)\n\tlogFlag := cmd.String(\"log\", \"\", \"\")\n\tgoplsLog := cmd.String(\"goplsLog\", \"\", \"\")\n\tgoplsRPCTrace := cmd.Bool(\"goplsRPCTrace\", false, \"\")\n\tgoplsRemote := cmd.String(\"gopls-remote\", \"\", \"\")\n\thelpFlag := cmd.Bool(\"help\", false, \"\")\n\tpprofFlag := cmd.Bool(\"pprof\", false, \"\")\n\thttpDebugFlag := cmd.String(\"http\", \"\", \"\")\n\tnoPreloadFlag := cmd.Bool(\"no-preload\", false, \"\")\n\terr := cmd.Parse(args)\n\tif err != nil {\n\t\t_, _ = fmt.Fprint(stderr, lspUsageText)\n\t\treturn 64 // EX_USAGE\n\t}\n\tif *helpFlag {\n\t\t_, _ = fmt.Fprint(stdout, lspUsageText)\n\t\treturn\n\t}\n\n\terr = lspcmd.Run(stdin, stdout, stderr, lspcmd.Arguments{\n\t\tLog:           *logFlag,\n\t\tGoplsLog:      *goplsLog,\n\t\tGoplsRPCTrace: *goplsRPCTrace,\n\t\tGoplsRemote:   *goplsRemote,\n\t\tPPROF:         *pprofFlag,\n\t\tHTTPDebug:     *httpDebugFlag,\n\t\tNoPreload:     *noPreloadFlag && os.Getenv(\"GOPACKAGESDRIVER\") != \"\",\n\t})\n\tif err != nil {\n\t\t_, _ = fmt.Fprintln(stderr, err.Error())\n\t\treturn 1\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "cmd/templ/main_test.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestMain(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\targs           []string\n\t\texpectedStdout string\n\t\texpectedStderr string\n\t\texpectedCode   int\n\t}{\n\t\t{\n\t\t\tname:           \"no args prints usage\",\n\t\t\targs:           []string{},\n\t\t\texpectedStderr: usageText,\n\t\t\texpectedCode:   64, // EX_USAGE\n\t\t},\n\t\t{\n\t\t\tname:           `\"templ help\" prints help`,\n\t\t\targs:           []string{\"templ\", \"help\"},\n\t\t\texpectedStdout: usageText,\n\t\t\texpectedCode:   0,\n\t\t},\n\t\t{\n\t\t\tname:           `\"templ --help\" prints help`,\n\t\t\targs:           []string{\"templ\", \"--help\"},\n\t\t\texpectedStdout: usageText,\n\t\t\texpectedCode:   0,\n\t\t},\n\t\t{\n\t\t\tname:           `\"templ version\" prints version`,\n\t\t\targs:           []string{\"templ\", \"version\"},\n\t\t\texpectedStdout: templ.Version() + \"\\n\",\n\t\t\texpectedCode:   0,\n\t\t},\n\t\t{\n\t\t\tname:           `\"templ --version\" prints version`,\n\t\t\targs:           []string{\"templ\", \"--version\"},\n\t\t\texpectedStdout: templ.Version() + \"\\n\",\n\t\t\texpectedCode:   0,\n\t\t},\n\t\t{\n\t\t\tname:           `\"templ fmt --help\" prints usage`,\n\t\t\targs:           []string{\"templ\", \"fmt\", \"--help\"},\n\t\t\texpectedStdout: fmtUsageText,\n\t\t\texpectedCode:   0,\n\t\t},\n\t\t{\n\t\t\tname:           `\"templ lsp --help\" prints usage`,\n\t\t\targs:           []string{\"templ\", \"lsp\", \"--help\"},\n\t\t\texpectedStdout: lspUsageText,\n\t\t\texpectedCode:   0,\n\t\t},\n\t\t{\n\t\t\tname:           `\"templ info --help\" prints usage`,\n\t\t\targs:           []string{\"templ\", \"info\", \"--help\"},\n\t\t\texpectedStdout: infoUsageText,\n\t\t\texpectedCode:   0,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tstdin := strings.NewReader(\"\")\n\t\t\tstdout := bytes.NewBuffer(nil)\n\t\t\tstderr := bytes.NewBuffer(nil)\n\t\t\tactualCode := run(stdin, stdout, stderr, test.args)\n\n\t\t\tif actualCode != test.expectedCode {\n\t\t\t\tt.Errorf(\"expected code %v, got %v\", test.expectedCode, actualCode)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(test.expectedStdout, stdout.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t\tt.Error(\"expected stdout:\")\n\t\t\t\tt.Error(test.expectedStdout)\n\t\t\t\tt.Error(\"actual stdout:\")\n\t\t\t\tt.Error(stdout.String())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(test.expectedStderr, stderr.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t\tt.Error(\"expected stderr:\")\n\t\t\t\tt.Error(test.expectedStderr)\n\t\t\t\tt.Error(\"actual stderr:\")\n\t\t\t\tt.Error(stderr.String())\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/processor/processor.go",
    "content": "package processor\n\nimport (\n\t\"io/fs\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/internal/skipdir\"\n)\n\ntype Result struct {\n\tFileName    string\n\tDuration    time.Duration\n\tError       error\n\tChangesMade bool\n}\n\nfunc Process(dir string, f func(fileName string) (error, bool), workerCount int, results chan<- Result) {\n\ttemplates := make(chan string)\n\tgo func() {\n\t\tdefer close(templates)\n\t\tif err := FindTemplates(dir, templates); err != nil {\n\t\t\tresults <- Result{Error: err}\n\t\t}\n\t}()\n\tProcessChannel(templates, dir, f, workerCount, results)\n}\n\nfunc FindTemplates(srcPath string, output chan<- string) (err error) {\n\treturn filepath.WalkDir(srcPath, func(currentPath string, info fs.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif info.IsDir() && skipdir.ShouldSkip(currentPath) {\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\tif !info.IsDir() && strings.HasSuffix(currentPath, \".templ\") {\n\t\t\toutput <- currentPath\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc ProcessChannel(templates <-chan string, dir string, f func(fileName string) (error, bool), workerCount int, results chan<- Result) {\n\tdefer close(results)\n\tvar wg sync.WaitGroup\n\twg.Add(workerCount)\n\tfor range workerCount {\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tfor sourceFileName := range templates {\n\t\t\t\tstart := time.Now()\n\t\t\t\toutErr, outChanged := f(sourceFileName)\n\t\t\t\tresults <- Result{\n\t\t\t\t\tFileName:    sourceFileName,\n\t\t\t\t\tError:       outErr,\n\t\t\t\t\tDuration:    time.Since(start),\n\t\t\t\t\tChangesMade: outChanged,\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n\twg.Wait()\n}\n"
  },
  {
    "path": "cmd/templ/processor/processor_test.go",
    "content": "package processor\n\nimport (\n\t\"os\"\n\t\"testing\"\n)\n\nfunc TestFindTemplates(t *testing.T) {\n\tt.Run(\"returns an error if the directory does not exist\", func(t *testing.T) {\n\t\toutput := make(chan string)\n\t\terr := FindTemplates(\"nonexistent\", output)\n\t\tif err == nil {\n\t\t\tt.Fatal(\"expected error, but got nil\")\n\t\t}\n\t\tif !os.IsNotExist(err) {\n\t\t\tt.Fatalf(\"expected os.IsNotExist(err) to be true, but got: %v\", err)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "cmd/templ/sloghandler/handler.go",
    "content": "package sloghandler\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"log/slog\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/fatih/color\"\n)\n\nfunc NewLogger(logLevel string, verbose bool, stderr io.Writer) *slog.Logger {\n\tif verbose {\n\t\tlogLevel = \"debug\"\n\t}\n\tlevel := slog.LevelInfo.Level()\n\tswitch logLevel {\n\tcase \"debug\":\n\t\tlevel = slog.LevelDebug.Level()\n\tcase \"warn\":\n\t\tlevel = slog.LevelWarn.Level()\n\tcase \"error\":\n\t\tlevel = slog.LevelError.Level()\n\t}\n\treturn slog.New(NewHandler(stderr, &slog.HandlerOptions{\n\t\tAddSource: logLevel == \"debug\",\n\t\tLevel:     level,\n\t}))\n}\n\nvar _ slog.Handler = &Handler{}\n\ntype Handler struct {\n\th slog.Handler\n\tm *sync.Mutex\n\tw io.Writer\n}\n\nvar levelToIcon = map[slog.Level]string{\n\tslog.LevelDebug: \"(✓)\",\n\tslog.LevelInfo:  \"(✓)\",\n\tslog.LevelWarn:  \"(!)\",\n\tslog.LevelError: \"(✗)\",\n}\nvar levelToColor = map[slog.Level]*color.Color{\n\tslog.LevelDebug: color.New(color.FgCyan),\n\tslog.LevelInfo:  color.New(color.FgGreen),\n\tslog.LevelWarn:  color.New(color.FgYellow),\n\tslog.LevelError: color.New(color.FgRed),\n}\n\nfunc NewHandler(w io.Writer, opts *slog.HandlerOptions) *Handler {\n\tif opts == nil {\n\t\topts = &slog.HandlerOptions{}\n\t}\n\treturn &Handler{\n\t\tw: w,\n\t\th: slog.NewTextHandler(w, &slog.HandlerOptions{\n\t\t\tLevel:     opts.Level,\n\t\t\tAddSource: opts.AddSource,\n\t\t\tReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {\n\t\t\t\tif opts.ReplaceAttr != nil {\n\t\t\t\t\ta = opts.ReplaceAttr(groups, a)\n\t\t\t\t}\n\t\t\t\tif a.Key == slog.LevelKey {\n\t\t\t\t\tlevel, ok := levelToIcon[a.Value.Any().(slog.Level)]\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tlevel = a.Value.Any().(slog.Level).String()\n\t\t\t\t\t}\n\t\t\t\t\ta.Value = slog.StringValue(level)\n\t\t\t\t\treturn a\n\t\t\t\t}\n\t\t\t\tif a.Key == slog.TimeKey {\n\t\t\t\t\treturn slog.Attr{}\n\t\t\t\t}\n\t\t\t\treturn a\n\t\t\t},\n\t\t}),\n\t\tm: &sync.Mutex{},\n\t}\n}\n\nfunc (h *Handler) Enabled(ctx context.Context, level slog.Level) bool {\n\treturn h.h.Enabled(ctx, level)\n}\n\nfunc (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler {\n\treturn &Handler{h: h.h.WithAttrs(attrs), w: h.w, m: h.m}\n}\n\nfunc (h *Handler) WithGroup(name string) slog.Handler {\n\treturn &Handler{h: h.h.WithGroup(name), w: h.w, m: h.m}\n}\n\nvar keyValueColor = color.New(color.Faint & color.FgBlack)\n\nfunc (h *Handler) Handle(ctx context.Context, r slog.Record) (err error) {\n\tvar sb strings.Builder\n\n\tsb.WriteString(levelToColor[r.Level].Sprint(levelToIcon[r.Level]))\n\tsb.WriteString(\" \")\n\tsb.WriteString(r.Message)\n\n\tif r.NumAttrs() != 0 {\n\t\tsb.WriteString(\" [\")\n\t\tr.Attrs(func(a slog.Attr) bool {\n\t\t\tsb.WriteString(keyValueColor.Sprintf(\" %s=%s\", a.Key, a.Value.String()))\n\t\t\treturn true\n\t\t})\n\t\tsb.WriteString(\" ]\")\n\t}\n\n\tsb.WriteString(\"\\n\")\n\n\th.m.Lock()\n\tdefer h.m.Unlock()\n\t_, err = io.WriteString(h.w, sb.String())\n\treturn err\n}\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/css-classes/classes.go",
    "content": "package cssclasses\n\nconst Header = \"header\"\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/go.mod.embed",
    "content": "module templ/testproject\n\ngo 1.25.0\n\nrequire github.com/a-h/templ v0.3.847 // indirect\n\nreplace github.com/a-h/templ => {moduleRoot}\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/go.sum",
    "content": "github.com/a-h/templ v0.3.833 h1:L/KOk/0VvVTBegtE0fp2RJQiBm7/52Zxv5fqlEHiQUU=\ngithub.com/a-h/templ v0.3.833/go.mod h1:cAu4AiZhtJfBjMY0HASlyzvkrtjnHWPeEsyGK2YYmfk=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/main.go",
    "content": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/a-h/templ\"\n)\n\nvar flagPort = flag.Int(\"port\", 0, \"Set the HTTP listen port\")\n\nfunc main() {\n\tflag.Parse()\n\n\tif *flagPort == 0 {\n\t\tfmt.Println(\"missing port flag\")\n\t\tos.Exit(1)\n\t}\n\n\tvar count int\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tcount++\n\t\tc := Page(count)\n\t\ttempl.Handler(c).ServeHTTP(w, r)\n\t})\n\terr := http.ListenAndServe(fmt.Sprintf(\"localhost:%d\", *flagPort), nil)\n\tif err != nil {\n\t\tfmt.Printf(\"Error listening: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/remotechild.templ",
    "content": "package main\n\ntempl Remote() {\n\t<p>This is remote content</p>\n}\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/remotechild_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Remote() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<p>This is remote content</p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/remoteparent.templ",
    "content": "package main\n\ntempl RemoteInclusionTest() {\n\t@Remote\n}\n\ntempl Remote2() {\n\t@Remote\n}\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/remoteparent_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc RemoteInclusionTest() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = Remote.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc Remote2() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var2 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var2 == nil {\n\t\t\ttempl_7745c5c3_Var2 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = Remote.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/templates.templ",
    "content": "package main\n\nimport \"fmt\"\n\ntempl Page(count int) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<title>templ test page</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>Count</h1>\n\t\t\t<div data-testid=\"count\">{ fmt.Sprintf(\"%d\", count) }</div>\n\t\t\t<div data-testid=\"modification\">Original</div>\n\t\t</body>\n\t</html>\n}\n\nvar nihao = \"你好\"\n\ntype Struct struct {\n\tCount int\n}\n\nvar s = Struct{}\n"
  },
  {
    "path": "cmd/templ/testproject/testdata/templates_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"fmt\"\n\nfunc Page(count int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype html><html><head><title>templ test page</title></head><body><h1>Count</h1><div data-testid=\\\"count\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(\"%d\", count))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/testproject/testdata/templates.templ`, Line: 13, Col: 54}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div><div data-testid=\\\"modification\\\">Original</div></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar nihao = \"你好\"\n\ntype Struct struct {\n\tCount int\n}\n\nvar s = Struct{}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "cmd/templ/testproject/testproject.go",
    "content": "package testproject\n\nimport (\n\t\"bytes\"\n\t\"embed\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n//go:embed testdata/*\nvar testdata embed.FS\n\nfunc Create(moduleRoot string) (dir string, err error) {\n\tdir, err = os.MkdirTemp(\"\", \"templ_test_*\")\n\tif err != nil {\n\t\treturn dir, fmt.Errorf(\"failed to make test dir: %w\", err)\n\t}\n\tfiles, err := testdata.ReadDir(\"testdata\")\n\tif err != nil {\n\t\treturn dir, fmt.Errorf(\"failed to read embedded dir: %w\", err)\n\t}\n\tfor _, file := range files {\n\t\tif file.IsDir() {\n\t\t\tif err = os.MkdirAll(filepath.Join(dir, file.Name()), 0777); err != nil {\n\t\t\t\treturn dir, fmt.Errorf(\"failed to create dir: %w\", err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tsrc := filepath.Join(\"testdata\", file.Name())\n\t\tdata, err := testdata.ReadFile(src)\n\t\tif err != nil {\n\t\t\treturn dir, fmt.Errorf(\"failed to read file: %w\", err)\n\t\t}\n\n\t\ttarget := filepath.Join(dir, file.Name())\n\t\tif file.Name() == \"go.mod.embed\" {\n\t\t\tdata = bytes.ReplaceAll(data, []byte(\"{moduleRoot}\"), []byte(moduleRoot))\n\t\t\ttarget = filepath.Join(dir, \"go.mod\")\n\t\t}\n\t\terr = os.WriteFile(target, data, 0660)\n\t\tif err != nil {\n\t\t\treturn dir, fmt.Errorf(\"failed to copy file: %w\", err)\n\t\t}\n\t}\n\tfiles, err = testdata.ReadDir(\"testdata/css-classes\")\n\tif err != nil {\n\t\treturn dir, fmt.Errorf(\"failed to read embedded dir: %w\", err)\n\t}\n\tfor _, file := range files {\n\t\tsrc := filepath.Join(\"testdata\", \"css-classes\", file.Name())\n\t\tdata, err := testdata.ReadFile(src)\n\t\tif err != nil {\n\t\t\treturn dir, fmt.Errorf(\"failed to read file: %w\", err)\n\t\t}\n\t\ttarget := filepath.Join(dir, \"css-classes\", file.Name())\n\t\terr = os.WriteFile(target, data, 0660)\n\t\tif err != nil {\n\t\t\treturn dir, fmt.Errorf(\"failed to copy file: %w\", err)\n\t\t}\n\t}\n\treturn dir, nil\n}\n\nfunc MustReplaceLine(file string, line int, replacement string) string {\n\tlines := strings.Split(file, \"\\n\")\n\tlines[line-1] = replacement\n\treturn strings.Join(lines, \"\\n\")\n}\n"
  },
  {
    "path": "cmd/templ/visualize/sourcemapvisualisation.templ",
    "content": "package visualize\n\ncss row() {\n\tdisplay: flex;\n}\n\ncss column() {\n\tflex: 50%;\n\toverflow-y: scroll;\n\tmax-height: 100vh;\n}\n\ncss code() {\n\tfont-family: monospace;\n}\n\ntempl combine(templFileName string, left, right templ.Component) {\n\t<html>\n\t\t<head>\n\t\t\t<title>{ templFileName }- Source Map Visualisation</title>\n\t\t\t<style type=\"text/css\">\n\t\t\t\t.mapped {\n\t\t\t\t\tbackground-color: green;\n\t\t\t\t}\n\t\t\t\t.highlighted {\n\t\t\t\t\tbackground-color: yellow;\n\t\t\t\t}\n\t\t\t</style>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>{ templFileName }</h1>\n\t\t\t<div class={ templ.Classes(row()) }>\n\t\t\t\t<div class={ templ.Classes(column(), code()) }>\n\t\t\t\t\t@left\n\t\t\t\t</div>\n\t\t\t\t<div class={ templ.Classes(column(), code()) }>\n\t\t\t\t\t@right\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</body>\n\t</html>\n}\n\nscript highlight(sourceId, targetId string) {\n        let items = document.getElementsByClassName(sourceId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.add(\"highlighted\");\n\t}\n        items = document.getElementsByClassName(targetId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.add(\"highlighted\");\n\t}\n}\n\nscript removeHighlight(sourceId, targetId string) {\n        let items = document.getElementsByClassName(sourceId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.remove(\"highlighted\");\n\t}\n        items = document.getElementsByClassName(targetId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.remove(\"highlighted\");\n\t}\n}\n\ntempl mappedCharacter(s string, sourceID, targetID string) {\n\t<span class={ templ.Classes(templ.Class(\"mapped\"), templ.Class(sourceID), templ.Class(targetID)) } onMouseOver={ highlight(sourceID, targetID) } onMouseOut={ removeHighlight(sourceID, targetID) }>{ s }</span>\n}\n"
  },
  {
    "path": "cmd/templ/visualize/sourcemapvisualisation_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage visualize\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc row() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`display:flex;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`row`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc column() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`flex:50%;`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(`overflow-y:scroll;`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(`max-height:100vh;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`column`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc code() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`font-family:monospace;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`code`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc combine(templFileName string, left, right templ.Component) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<html><head><title>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(templFileName)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/visualize/sourcemapvisualisation.templ`, Line: 20, Col: 25}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"- Source Map Visualisation</title><style type=\\\"text/css\\\">\\n\\t\\t\\t\\t.mapped {\\n\\t\\t\\t\\t\\tbackground-color: green;\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t.highlighted {\\n\\t\\t\\t\\t\\tbackground-color: yellow;\\n\\t\\t\\t\\t}\\n\\t\\t\\t</style></head><body><h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templFileName)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/visualize/sourcemapvisualisation.templ`, Line: 31, Col: 22}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 = []any{templ.Classes(row())}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/visualize/sourcemapvisualisation.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 = []any{templ.Classes(column(), code())}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 string\n\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/visualize/sourcemapvisualisation.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = left.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var8 = []any{templ.Classes(column(), code())}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var9 string\n\t\ttempl_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var8).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/visualize/sourcemapvisualisation.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = right.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"</div></div></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc highlight(sourceId, targetId string) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_highlight_ae80`,\n\t\tFunction: `function __templ_highlight_ae80(sourceId, targetId){let items = document.getElementsByClassName(sourceId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.add(\"highlighted\");\n\t}\n        items = document.getElementsByClassName(targetId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.add(\"highlighted\");\n\t}\n}`,\n\t\tCall:       templ.SafeScript(`__templ_highlight_ae80`, sourceId, targetId),\n\t\tCallInline: templ.SafeScriptInline(`__templ_highlight_ae80`, sourceId, targetId),\n\t}\n}\n\nfunc removeHighlight(sourceId, targetId string) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_removeHighlight_58f2`,\n\t\tFunction: `function __templ_removeHighlight_58f2(sourceId, targetId){let items = document.getElementsByClassName(sourceId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.remove(\"highlighted\");\n\t}\n        items = document.getElementsByClassName(targetId);\n\tfor(let i = 0; i < items.length; i ++) {\n\t\titems[i].classList.remove(\"highlighted\");\n\t}\n}`,\n\t\tCall:       templ.SafeScript(`__templ_removeHighlight_58f2`, sourceId, targetId),\n\t\tCallInline: templ.SafeScriptInline(`__templ_removeHighlight_58f2`, sourceId, targetId),\n\t}\n}\n\nfunc mappedCharacter(s string, sourceID, targetID string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var10 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var10 == nil {\n\t\t\ttempl_7745c5c3_Var10 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var11 = []any{templ.Classes(templ.Class(\"mapped\"), templ.Class(sourceID), templ.Class(targetID))}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var11...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, highlight(sourceID, targetID), removeHighlight(sourceID, targetID))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"<span class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var12 string\n\t\ttempl_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var11).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/visualize/sourcemapvisualisation.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"\\\" onMouseOver=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var13 templ.ComponentScript = highlight(sourceID, targetID)\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var13.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, \"\\\" onMouseOut=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var14 templ.ComponentScript = removeHighlight(sourceID, targetID)\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var14.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var15 string\n\t\ttempl_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(s)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `cmd/templ/visualize/sourcemapvisualisation.templ`, Line: 67, Col: 200}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, \"</span>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "cmd/templ/visualize/types.go",
    "content": "package visualize\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"html\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\nfunc HTML(templFileName string, templContents, goContents string, sourceMap *parser.SourceMap) templ.Component {\n\ttl := templLines{contents: string(templContents), sourceMap: sourceMap}\n\tgl := goLines{contents: string(goContents), sourceMap: sourceMap}\n\treturn combine(templFileName, tl, gl)\n}\n\ntype templLines struct {\n\tcontents  string\n\tsourceMap *parser.SourceMap\n}\n\nfunc (tl templLines) Render(ctx context.Context, w io.Writer) (err error) {\n\ttemplLines := strings.Split(tl.contents, \"\\n\")\n\tfor lineIndex, line := range templLines {\n\t\tif _, err = w.Write([]byte(\"<span>\" + strconv.Itoa(lineIndex) + \"&nbsp;</span>\\n\")); err != nil {\n\t\t\treturn\n\t\t}\n\t\tfor colIndex, c := range line {\n\t\t\tif tgt, ok := tl.sourceMap.TargetPositionFromSource(uint32(lineIndex), uint32(colIndex)); ok {\n\t\t\t\tsourceID := fmt.Sprintf(\"src_%d_%d\", lineIndex, colIndex)\n\t\t\t\ttargetID := fmt.Sprintf(\"tgt_%d_%d\", tgt.Line, tgt.Col)\n\t\t\t\tif err := mappedCharacter(string(c), sourceID, targetID).Render(ctx, w); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ts := html.EscapeString(string(c))\n\t\t\t\ts = strings.ReplaceAll(s, \"\\t\", \"&nbsp;\")\n\t\t\t\ts = strings.ReplaceAll(s, \" \", \"&nbsp;\")\n\t\t\t\tif _, err := w.Write([]byte(s)); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif _, err = w.Write([]byte(\"\\n<br/>\\n\")); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn nil\n}\n\ntype goLines struct {\n\tcontents  string\n\tsourceMap *parser.SourceMap\n}\n\nfunc (gl goLines) Render(ctx context.Context, w io.Writer) (err error) {\n\ttemplLines := strings.Split(gl.contents, \"\\n\")\n\tfor lineIndex, line := range templLines {\n\t\tif _, err = w.Write([]byte(\"<span>\" + strconv.Itoa(lineIndex) + \"&nbsp;</span>\\n\")); err != nil {\n\t\t\treturn\n\t\t}\n\t\tfor colIndex, c := range line {\n\t\t\tif src, ok := gl.sourceMap.SourcePositionFromTarget(uint32(lineIndex), uint32(colIndex)); ok {\n\t\t\t\tsourceID := fmt.Sprintf(\"src_%d_%d\", src.Line, src.Col)\n\t\t\t\ttargetID := fmt.Sprintf(\"tgt_%d_%d\", lineIndex, colIndex)\n\t\t\t\tif err := mappedCharacter(string(c), sourceID, targetID).Render(ctx, w); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ts := html.EscapeString(string(c))\n\t\t\t\ts = strings.ReplaceAll(s, \"\\t\", \"&nbsp;\")\n\t\t\t\ts = strings.ReplaceAll(s, \" \", \"&nbsp;\")\n\t\t\t\tif _, err := w.Write([]byte(s)); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif _, err = w.Write([]byte(\"\\n<br/>\\n\")); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cosign.pub",
    "content": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqHp75uAj8XqKrLO2YvY0M2EddckH\nevQnNAj+0GmBptqdf3NJcUCjL6w4z2Ikh/Zb8lh6b13akAwO/dJQaMLoMA==\n-----END PUBLIC KEY-----\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "# Dependencies\n/node_modules\n\n# Production\n/build\n\n# Generated files\n.docusaurus\n.cache-loader\n\n# Misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n/static/llms.md\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Website\n\nThis website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.\n\n### Installation\n\n```\n$ yarn\n```\n\n### Local Development\n\n```\n$ yarn start\n```\n\nThis command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.\n\n### Build\n\n```\n$ yarn build\n```\n\nThis command generates static content into the `build` directory and can be served using any static contents hosting service.\n\n### Deployment\n\nUsing SSH:\n\n```\n$ USE_SSH=true yarn deploy\n```\n\nNot using SSH:\n\n```\n$ GIT_USER=<Your GitHub username> yarn deploy\n```\n\nIf you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.\n"
  },
  {
    "path": "docs/babel.config.js",
    "content": "module.exports = {\n  presets: [require.resolve('@docusaurus/core/lib/babel/preset')],\n};\n"
  },
  {
    "path": "docs/docs/02-quick-start/01-installation.md",
    "content": "# Installation\n\n## go install (global)\n\nWith Go 1.24 or greater installed, run:\n\n```bash\ngo install github.com/a-h/templ/cmd/templ@latest\n```\n\nThis installs templ into your path.\n\n## go install (as tool)\n\nTo install templ locally in your project, run:\n\n```bash\ngo get -tool github.com/a-h/templ/cmd/templ@latest\n```\n\n:::info \nThis uses the [tool directive](https://tip.golang.org/doc/modules/managing-dependencies#tools) feature of Go added in v1.24. \n\nTo run templ once installed, use `go tool templ` instead of `templ`.\n:::\n\n## GitHub binaries\n\nDownload the latest release from https://github.com/a-h/templ/releases/latest\n\n## Nix\n\ntempl provides a Nix flake with an exported package containing the binary at https://github.com/a-h/templ/blob/main/flake.nix\n\n```bash\nnix run github:a-h/templ\n```\n\ntempl also provides a development shell which includes all of the tools required to build templ, e.g. go, gopls etc. but not templ itself.\n\n```bash\nnix develop github:a-h/templ\n```\n\nTo install in your Nix Flake:\n\nThis flake exposes an overlay, so you can add it to your own Flake and/or NixOS system.\n\n```nix\n{\n  inputs = {\n    ...\n    templ.url = \"github:a-h/templ\";\n    ...\n  };\n  outputs = inputs@{\n    ...\n  }:\n\n  # For NixOS configuration:\n  {\n    # Add the overlay,\n    nixpkgs.overlays = [\n      inputs.templ.overlays.default\n    ];\n    # and install the package\n    environment.systemPackages = with pkgs; [\n      templ\n    ];\n  };\n\n  # For a flake project:\n  let\n    forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {\n      inherit system;\n      pkgs = import nixpkgs { inherit system; };\n    });\n    templ = system: inputs.templ.packages.${system}.templ;\n  in {\n    packages = forAllSystems ({ pkgs, system }: {\n      myNewPackage = pkgs.buildGoModule {\n        ...\n        preBuild = ''\n          ${templ system}/bin/templ generate\n        '';\n      };\n    });\n\n    devShell = forAllSystems ({ pkgs, system }:\n      pkgs.mkShell {\n        buildInputs = with pkgs; [\n          go\n          (templ system)\n        ];\n      };\n  });\n}\n```\n\n## Docker\n\nA Docker container is pushed on each release to https://github.com/a-h/templ/pkgs/container/templ\n\nPull the latest version with:\n\n```bash\ndocker pull ghcr.io/a-h/templ:latest\n```\n\nTo use the container, mount the source code of your application into the `/app` directory, set the working directory to the same directory and run `templ generate`, e.g. in a Linux or Mac shell, you can generate code for the current directory with:\n\n```bash\ndocker run -v `pwd`:/app -w=/app ghcr.io/a-h/templ:latest generate\n```\n\nIf you want to build templates using a multi-stage Docker build, you can use the `templ` image as a base image.\n\nHere's an example multi-stage Dockerfile. Note that in the `generate-stage` the source code is copied into the container, and the `templ generate` command is run. The `build-stage` then copies the generated code into the container and builds the application.\n\nThe permissions of the source code are set to a user with a UID of 65532, which is the UID of the `nonroot` user in the `ghcr.io/a-h/templ:latest` image.\n\nNote also the use of the `RUN [\"templ\", \"generate\"]` command instead of the common `RUN templ generate` command. This is because the templ Docker container does not contain a shell environment to keep its size minimal, so the command must be ran in the [\"exec\" form](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form).\n\n```Dockerfile\n# Fetch\nFROM golang:latest AS fetch-stage\nCOPY go.mod go.sum /app\nWORKDIR /app\nRUN go mod download\n\n# Generate\nFROM ghcr.io/a-h/templ:latest AS generate-stage\nCOPY --chown=65532:65532 . /app\nWORKDIR /app\nRUN [\"templ\", \"generate\"]\n\n# Build\nFROM golang:latest AS build-stage\nCOPY --from=generate-stage /app /app\nWORKDIR /app\nRUN CGO_ENABLED=0 GOOS=linux go build -o /app/app\n\n# Test\nFROM build-stage AS test-stage\nRUN go test -v ./...\n\n# Deploy\nFROM gcr.io/distroless/base-debian12 AS deploy-stage\nWORKDIR /\nCOPY --from=build-stage /app/app /app\nEXPOSE 8080\nUSER nonroot:nonroot\nENTRYPOINT [\"/app\"]\n```\n"
  },
  {
    "path": "docs/docs/02-quick-start/02-creating-a-simple-templ-component.md",
    "content": "# Creating a simple templ component\n\nTo create a templ component, first create a new Go project.\n\n## Setup project\n\nCreate a new directory containing our project.\n\n```bash\nmkdir hello-world\n```\n\nInitialize a new Go project within it.\n\n```bash\ncd hello-world\ngo mod init github.com/a-h/templ-examples/hello-world\ngo get github.com/a-h/templ\n```\n\n## Create a templ file\n\nTo use it, create a `hello.templ` file containing a component.\n\nComponents are functions that contain templ elements, markup, and `if`, `switch`, and `for` Go expressions.\n\n```templ title=\"hello.templ\"\npackage main\n\ntempl hello(name string) {\n\t<div>Hello, { name }</div>\n}\n```\n\n## Generate Go code from the templ file\n\nRun the `templ generate` command.\n\n```bash\ntempl generate\n```\n\ntempl will generate a `hello_templ.go` file containing Go code.\n\nThis file will contain a function called `hello` which takes `name` as an argument, and returns a `templ.Component` that renders HTML.\n\n```go\nfunc hello(name string) templ.Component {\n  // ...\n}\n```\n\n## Write a program that renders to stdout\n\nCreate a `main.go` file.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\tcomponent := hello(\"John\")\n\tcomponent.Render(context.Background(), os.Stdout)\n}\n```\n\n## Run the program\n\nRunning the code will render the component's HTML to stdout.\n\n```bash\ngo run .\n```\n\n```html title=\"Output\"\n<div>Hello, John</div>\n```\n\nInstead of passing `os.Stdout` to the component's render function, you can pass any type that implements the `io.Writer` interface. This includes files, `bytes.Buffer`, and HTTP responses.\n\nIn this way, templ can be used to generate HTML files that can be hosted as static content in an S3 bucket, Google Cloud Storage, or used to generate HTML that is fed into PDF conversion processes, or sent via email.\n"
  },
  {
    "path": "docs/docs/02-quick-start/03-running-your-first-templ-application.md",
    "content": "# Running your first templ application\n\nLet's update the previous application to serve HTML over HTTP instead of writing it to the terminal.\n\n## Create a web server\n\nUpdate the `main.go` file.\n\ntempl components can be served as a standard HTTP handler using the `templ.Handler` function.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\tcomponent := hello(\"John\")\n\t\n\thttp.Handle(\"/\", templ.Handler(component))\n\n\tfmt.Println(\"Listening on :3000\")\n\thttp.ListenAndServe(\":3000\", nil)\n}\n```\n\n## Run the program\n\nRunning the code will start a web server on port 3000.\n\n```bash\ngo run *.go\n```\n\nIf you run another terminal session and run `curl` you can see the exact HTML that is returned matches the `hello` component, with the name \"John\".\n\n```bash\ncurl localhost:3000\n```\n\n```html name=\"Output\"\n<div>Hello, John</div>\n```\n"
  },
  {
    "path": "docs/docs/02-quick-start/_category_.json",
    "content": "{\n  \"position\": 2,\n  \"label\": \"Quick start\"\n}\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/01-basic-syntax.md",
    "content": "# Basic syntax\n\n## Package name and imports\n\ntempl files start with a package name, followed by any required imports, just like Go.\n\n```go\npackage main\n\nimport \"fmt\"\nimport \"time\"\n```\n\n## Components\n\ntempl files can also contain components. Components are markup and code that is compiled into functions that return a `templ.Component` interface by running the `templ generate` command.\n\nComponents can contain templ elements that render HTML, text, expressions that output text or include other templates, and branching statements such as `if` and `switch`, and `for` loops.\n\n```templ name=\"header.templ\"\npackage main\n\ntempl headerTemplate(name string) {\n  <header data-testid=\"headerTemplate\">\n    <h1>{ name }</h1>\n  </header>\n}\n```\n\n## Go code\n\nOutside of templ Components, templ files are ordinary Go code.\n\n```templ name=\"header.templ\"\npackage main\n\n// Ordinary Go code that we can use in our Component.\nvar greeting = \"Welcome!\"\n\n// templ Component\ntempl headerTemplate(name string) {\n  <header>\n    <h1>{ name }</h1>\n    <h2>\"{ greeting }\" comes from ordinary Go code</h2>\n  </header>\n}\n```\n\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/02-elements.md",
    "content": "# Elements\n\ntempl elements are used to render HTML within templ components.\n\n```templ title=\"button.templ\"\npackage main\n\ntempl button(text string) {\n\t<button class=\"button\">{ text }</button>\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\tbutton(\"Click me\").Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<button class=\"button\">\n Click me\n</button>\n```\n\n:::info\ntempl automatically minifies HTML responses, output is shown formatted for readability.\n:::\n\n## Tags must be closed\n\nUnlike HTML, templ requires that all HTML elements are closed with either a closing tag (`</a>`), or by using a self-closing element (`<hr/>`).\n\ntempl is aware of which HTML elements are \"void\", and will not include the closing `/` in the output HTML.\n\n```templ title=\"button.templ\"\npackage main\n\ntempl component() {\n\t<div>Test</div>\n\t<img src=\"images/test.png\"/>\n\t<br/>\n}\n```\n\n```templ title=\"Output\"\n<div>Test</div>\n<img src=\"images/test.png\">\n<br>\n```\n\n## Attributes and elements can contain expressions\n\ntempl elements can contain placeholder expressions for attributes and content.\n\n```templ title=\"button.templ\"\npackage main\n\ntempl button(name string, content string) {\n\t<button value={ name }>{ content }</button>\n}\n```\n\nRendering the component to stdout, we can see the results.\n\n```go title=\"main.go\"\nfunc main() {\n\tcomponent := button(\"John\", \"Say Hello\")\n\tcomponent.Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<button value=\"John\">Say Hello</button>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/03-attributes.md",
    "content": "# Attributes\n\n## Constant attributes\n\ntempl elements can have HTML attributes that use the double quote character `\"`.\n\n```templ\ntempl component() {\n  <p data-testid=\"paragraph\">Text</p>\n}\n```\n\n```html title=\"Output\"\n<p data-testid=\"paragraph\">Text</p>\n```\n\n## String expression attributes\n\nElement attributes can be set to Go strings.\n\n```templ\ntempl component(testID string) {\n  <p data-testid={ testID }>Text</p>\n}\n\ntempl page() {\n  @component(\"testid-123\")\n}\n```\n\nRendering the `page` component results in:\n\n```html title=\"Output\"\n<p data-testid=\"testid-123\">Text</p>\n```\n\n:::note\nString values are automatically HTML attribute encoded. This is a security measure, but may make the values (especially JSON appear) look strange to you, since some characters may be converted into HTML entities. However, it is correct HTML and won't affect the behavior. \n:::\n\nIt's also possible to use function calls in string attribute expressions.\n\nHere's a function that returns a string based on a boolean input.\n\n```go\nfunc testID(isTrue bool) string {\n    if isTrue {\n        return \"testid-123\"\n    }\n    return \"testid-456\"\n}\n```\n\n```templ\ntempl component() {\n  <p data-testid={ testID(true) }>Text</p>\n}\n```\n\nThe result:\n\n```html title=\"Output\"\n<p data-testid=\"testid-123\">Text</p>\n```\n\nFunctions in string attribute expressions can also return errors.\n\n```go\nfunc testID(isTrue bool) (string, error) {\n    if isTrue {\n        return \"testid-123\", nil\n    }\n    return \"\", fmt.Errorf(\"isTrue is false\")\n}\n```\n\nIf the function returns an error, the `Render` method will return the error along with its location.\n\n## Boolean attributes\n\nBoolean attributes (see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes) where the presence of an attribute name without a value means true, and the attribute name not being present means false are supported.\n\n```templ\ntempl component() {\n  <hr noshade/>\n}\n```\n\n```html title=\"Output\"\n<hr noshade>\n```\n\n:::note\ntempl is aware that `<hr/>` is a void element, and renders `<hr>` instead.\n:::\n\n\nTo set boolean attributes using variables or template parameters, a question mark after the attribute name is used to denote that the attribute is boolean.\n\n```templ\ntempl component() {\n  <hr noshade?={ false } />\n}\n```\n\n```html title=\"Output\"\n<hr>\n```\n\n## Conditional attributes\n\nUse an `if` statement within a templ element to optionally add attributes to elements.\n\n```templ\ntempl component() {\n  <hr style=\"padding: 10px\"\n    if true {\n      class=\"itIsTrue\"\n    }\n  />\n}\n```\n\n```html title=\"Output\"\n<hr style=\"padding: 10px\" class=\"itIsTrue\" />\n```\n\n## Attribute key expressions\n\nUse a string expression to dynamically set the key of an attribute.\n\n```templ\ntempl paragraph(testID string) {\n  <p { \"data-\" + testID }=\"paragraph\">Text</p>\n}\n\ntempl component() {\n  @paragraph(\"testid\")\n}\n```\n\n```html title=\"Output\"\n<p data-testid=\"paragraph\">Text</p>\n```\n\n:::warning\nCurrently, attribute types with special handling like `href`, `onClick`, and `on*` are not handled differently when defined with an expression key. So if you use a string expression to set the key of an attribute, it will be treated as a normal string attribute, without type specific escaping.\n:::\n\n## Spread attributes\n\nUse the `{ attrMap... }` syntax in the open tag of an element to append a dynamic map of attributes to the element's attributes.\n\nIt's possible to spread any variable of type `templ.Attributes`. `templ.Attributes` is a `map[string]any` type definition.\n\n* If the value is a `string`, the attribute is added with the string value, e.g. `<div name=\"value\">`.\n* If the value is a `bool`, the attribute is added as a boolean attribute if the value is true, e.g. `<div name>`.\n* If the value is a `templ.KeyValue[string, bool]`, the attribute is added if the boolean is true, e.g. `<div name=\"value\">`.\n* If the value is a `templ.KeyValue[bool, bool]`, the attribute is added if both boolean values are true, as `<div name>`.\n\n```templ\ntempl component(shouldBeUsed bool, attrs templ.Attributes) {\n  <p { attrs... }>Text</p>\n  <hr\n    if shouldBeUsed {\n      { attrs... }\n    }\n  />\n}\n\ntempl usage() {\n  @component(false, templ.Attributes{\"data-testid\": \"paragraph\"}) \n}\n```\n\n```html title=\"Output\"\n<p data-testid=\"paragraph\">Text</p>\n<hr>\n```\n\n## URL attributes\n\nAttributes that expect a URL, such as `<a href={ url }>`, `<form action={ url }>`, or `<img src={ url }>`, have special behavior if you use a dynamic value.\n\n```templ\ntempl component(p Person) {\n  <a href={ p.URL }>{ strings.ToUpper(p.Name) }</a>\n}\n```\n\nWhen you pass a `string` to these attributes, templ will automatically sanitize the input URL, ensuring that the protocol is safe (e.g., `http`, `https`, or `mailto`) and does not contain potentially harmful protocols like `javascript:`.\n\n:::caution\nTo bypass URL sanitization, you can use `templ.SafeURL(myURL)` to mark that your string is safe to use.\n\nThis may introduce security vulnerabilities to your program.\n:::\n\nIf you use a constant value, e.g. `<a href=\"javascript:alert('hello')\">`, templ will not modify it, and it will be rendered as is.\n\n:::tip\nNon-standard HTML attributes can contain URLs, for example htmx's `hx-*` attributes).\n\nTo sanitize URLs in that context, use the `templ.URL(urlString)` function.\n\n```templ\ntempl component(contact model.Contact) {\n  <div hx-get={ templ.URL(fmt.Sprintf(\"/contacts/%s/email\", contact.ID)) }>\n    { contact.Name }\n  </div>\n}\n```\n:::\n\n:::note\nIn templ, all attributes are HTML-escaped. This means that:\n\n- `&` characters in the URL are escaped to `&amp;`.\n- `\"` characters are escaped to `&quot;`.\n- `'` characters are escaped to `&#39;`.\n\nThis done to prevent XSS attacks. For example, without escaping, if a string contained `http://google.com\" onclick=\"alert('hello')\"`, the browser would interpret this as a URL followed by an `onclick` attribute, which would execute JavaScript code.\n\nThe escaping does not change the URL's functionality.\n\nSanitization is the process of examining the URL scheme (protocol) and structure to ensure that it's safe to use, e.g. that it doesn't contain `javascript:` or other potentially harmful schemes. If a URL is not safe, templ will replace the URL with `about:invalid#TemplFailedSanitizationURL`.\n:::\n\n## JavaScript attributes\n\n`onClick` and other `on*` handlers have special behaviour, they expect a reference to a `script` template.\n\n:::info\nThis ensures that any client-side JavaScript that is required for a component to function is only emitted once, that script name collisions are not possible, and that script input parameters are properly sanitized.\n:::\n\n```templ\nscript withParameters(a string, b string, c int) {\n\tconsole.log(a, b, c);\n}\n\nscript withoutParameters() {\n\talert(\"hello\");\n}\n\ntempl Button(text string) {\n\t<button onClick={ withParameters(\"test\", text, 123) } onMouseover={ withoutParameters() } type=\"button\">{ text }</button>\n}\n```\n\n```html title=\"Output\"\n<script>\n function __templ_withParameters_1056(a, b, c){console.log(a, b, c);}function __templ_withoutParameters_6bbf(){alert(\"hello\");}\n</script>\n<button onclick=\"__templ_withParameters_1056(\"test\",\"Say hello\",123)\" onmouseover=\"__templ_withoutParameters_6bbf()\" type=\"button\">\n Say hello\n</button>\n```\n\n## CSS attributes\n\nCSS handling is discussed in detail in [CSS style management](/syntax-and-usage/css-style-management).\n\n## JSON attributes\n\nTo set an attribute's value to a JSON string (e.g. for htmx's [hx-vals](https://htmx.org/attributes/hx-vals) or Alpine's [x-data](https://alpinejs.dev/directives/data)), serialize the value to a string using a function.\n\n```go\nfunc countriesJSON() string {\n\tcountries := []string{\"Czech Republic\", \"Slovakia\", \"United Kingdom\", \"Germany\", \"Austria\", \"Slovenia\"}\n\tbytes, _ := json.Marshal(countries)\n\treturn string(bytes)\n}\n```\n\n```templ\ntempl SearchBox() {\n\t<search-webcomponent suggestions={ countriesJSON() } />\n}\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/04-expressions.md",
    "content": "# Expressions\n\n## Interpolation expressions\n\nWithin a templ element, expressions can be used to interpolate Go values. Content is automatically escaped using context-aware HTML encoding rules to protect against XSS and CSS injection attacks.\n\nLiterals, variables and functions that return a value can be used. \n\nThe supported types for interpolation are:\n\n- Strings\n- Numbers (`int`, `uint`, `float32`, `complex64` etc.)\n- Booleans\n\n:::note\nAny type based on the above list can be used, for example `type Age int` or `type Name string`.\n:::\n\n### Literals\n\nYou can use Go literals.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl component() {\n  <div>{ \"print this\" }</div>\n  <div>{ `and this` }</div>\n  <div>Number of the day: { 1 }</div>\n}\n```\n\n```html title=\"Output\"\n<div>print this</div><div>and this</div><div>Number of the day: 1</div>\n```\n\n### Variables\n\nAny supported Go variable can be used, for example:\n\n* A function parameter.\n* A field on a struct.\n* A variable or constant that is in scope.\n\n```templ title=\"/main.templ\"\npackage main\n\ntempl greet(prefix string, p Person) {\n  <div>{ prefix } { p.Name }{ exclamation }</div>\n  <div>Congratulations on being { p.Age }!</div>\n}\n```\n\n```templ title=\"main.go\"\npackage main\n\ntype Person struct {\n  Name string\n  Age  int\n}\n\nconst exclamation = \"!\"\n\nfunc main() {\n  p := Person{ Name: \"John\", Age: 42 }\n  component := greet(\"Hello\", p) \n  component.Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<div>Hello John!</div><div>Congratulations on being 42!</div>\n```\n\n### Functions\n\nFunctions that return a value, or a value-error tuple can be used.\n\n```templ title=\"component.templ\"\npackage main\n\nimport \"strings\"\nimport \"strconv\"\n\nfunc getString() (string, error) {\n  return \"DEF\", nil\n}\n\ntempl component() {\n  <div>{ strings.ToUpper(\"abc\") }</div>\n  <div>{ getString() }</div>\n}\n```\n\n```html title=\"Output\"\n<div>ABC</div>\n<div>DEF</div>\n```\n\nIf the function returns an error, the `Render` function will return an error containing the location of the error and the underlying error.\n\n### Escaping\n\ntempl automatically escapes strings using HTML escaping rules.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl component() {\n  <div>{ `</div><script>alert('hello!')</script><div>` }</div>\n}\n```\n\n```html title=\"Output\"\n<div>&lt;/div&gt;&lt;script&gt;alert(&#39;hello!&#39;)&lt;/script&gt;&lt;div&gt;</div>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/05-statements.md",
    "content": "# Statements\n\n## Control flow\n\nWithin a templ element, a subset of Go statements can be used directly.\n\nThese Go statements can be used to conditionally render child elements, or to iterate variables.\n\nFor individual implementation guides see:\n\n* [if/else](/syntax-and-usage/if-else)\n* [switch](/syntax-and-usage/switch)\n* [for loops](/syntax-and-usage/loops)\n\n## if/switch/for within text\n\nGo statements can be used without any escaping to make it simple for developers to include them.\n\nThe templ parser assumes that text that starts with `if`, `switch` or `for` denotes the start of one of those expressions as per this example.\n\n```templ title=\"show-hello.templ\"\npackage main\n\ntempl showHelloIfTrue(b bool) {\n\t<div>\n\t\tif b {\n\t\t\t<p>Hello</p>\n\t\t}\n\t</div>\n}\n```\n\nIf you need to start a text block with the words `if`, `switch`, or `for`:\n\n* Use a Go string expression.\n* Capitalise `if`, `switch`, or `for`.\n\n```templ title=\"paragraph.templ\"\npackage main\n\ntempl display(price float64, count int) {\n\t<p>Switch to Linux</p>\n\t<p>{ `switch to Linux` }</p>\n\t<p>{ \"for a day\" }</p>\n\t<p>{ fmt.Sprintf(\"%f\", price) }{ \"for\" }{ fmt.Sprintf(\"%d\", count) }</p>\n\t<p>{ fmt.Sprintf(\"%f for %d\", price, count) }</p>\n}\n```\n\n## Design considerations\n\nWe decided to not require a special prefix for `if`, `switch` and `for` expressions on the basis that we were more likely to want to use a Go control statement than start a text run with those strings.\n\nTo reduce the risk of a broken control statement, resulting in printing out the source code of the application, templ will complain if a text run starts with `if`, `switch` or `for`, but no opening brace `{` is found.\n\nFor example, the following code causes the templ parser to return an error:\n\n```templ title=\"broken-if.templ\"\npackage main\n\ntempl showIfTrue(b bool) {\n\tif b \n\t  <p>Hello</p>\n\t}\n}\n```\n\n:::note\nNote the missing `{` on line 4.\n:::\n\nThe following code also produces an error, since the text run starts with `if`, but no opening `{` is found.\n\n```templ title=\"paragraph.templ\"\npackage main\n\ntempl text(b bool) {\n\t<p>if a tree fell in the woods</p>\n}\n```\n\n:::note\nThis also applies to `for` and `switch` statements.\n:::\n\nTo resolve the issue:\n\n* Use a Go string expression.\n* Capitalise `if`, `switch`, or `for`.\n\n```templ title=\"paragraph.templ\"\npackage main\n\ntempl display(price float64, count int) {\n\t<p>Switch to Linux</p>\n\t<p>{ `switch to Linux` }</p>\n\t<p>{ \"for a day\" }</p>\n\t<p>{ fmt.Sprintf(\"%f\", price) }{ \"for\" }{ fmt.Sprintf(\"%d\", count) }</p>\n\t<p>{ fmt.Sprintf(\"%f for %d\", price, count) }</p>\n}\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/06-if-else.md",
    "content": "# If/else\n\ntempl uses standard Go `if`/`else` statements which can be used to conditionally render components and elements.\n\n```templ title=\"component.templ\"\ntempl login(isLoggedIn bool) {\n  if isLoggedIn {\n    <div>Welcome back!</div>\n  } else {\n    <input name=\"login\" type=\"button\" value=\"Log in\"/>\n  }\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\tlogin(true).Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<div>\n Welcome back!\n</div>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/07-switch.md",
    "content": "# Switch\n\ntempl uses standard Go `switch` statements which can be used to conditionally render components and elements.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl userTypeDisplay(userType string) {\n\tswitch userType {\n\t\tcase \"test\":\n\t\t\t<span>{ \"Test user\" }</span>\n\t\tcase \"admin\":\n\t\t\t<span>{ \"Admin user\" }</span>\n\t\tdefault:\n\t\t\t<span>{ \"Unknown user\" }</span>\n\t}\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\tuserTypeDisplay(\"Other\").Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<span>\n Unknown user\n</span>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/08-loops.md",
    "content": "# For loops\n\nUse the standard Go `for` loop for iteration.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl nameList(items []Item) {\n  <ul>\n  for _, item := range items {\n    <li>{ item.Name }</li>\n  }\n  </ul>\n}\n```\n\n```html title=\"Output\"\n<ul>\n  <li>A</li>\n  <li>B</li>\n  <li>C</li>\n</ul>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/09-raw-go.md",
    "content": "# Raw Go\n\nFor some more advanced use cases it may be useful to write Go code statements in your template.\n\nUse the `{{ ... }}` syntax for this.\n\n## Variable declarations\n\nScoped variables can be created using this syntax, to reduce the need for multiple function calls.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl nameList(items []Item) {\n    {{ first := items[0] }}\n    <p>\n        { first.Name }\n    </p>\n}\n```\n\n```html title=\"Output\"\n<p>A</p>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/10-template-composition.md",
    "content": "# Template composition\n\nTemplates can be composed using the import expression.\n\n```templ\ntempl showAll() {\n\t@left()\n\t@middle()\n\t@right()\n}\n\ntempl left() {\n\t<div>Left</div>\n}\n\ntempl middle() {\n\t<div>Middle</div>\n}\n\ntempl right() {\n\t<div>Right</div>\n}\n```\n\n```html title=\"Output\"\n<div>\n Left\n</div>\n<div>\n Middle\n</div>\n<div>\n Right\n</div>\n```\n\n## Children\n\nChildren can be passed to a component for it to wrap.\n\n```templ\ntempl showAll() {\n\t@wrapChildren() {\n\t\t<div>Inserted from the top</div>\n\t}\n}\n\ntempl wrapChildren() {\n\t<div id=\"wrapper\">\n\t\t{ children... }\n\t</div>\n}\n```\n\n:::note\nThe use of the `{ children... }` expression in the child component.\n:::\n\n```html title=\"output\"\n<div id=\"wrapper\">\n <div>\n  Inserted from the top\n </div>\n</div>\n```\n\n### Using children in code components\n\nChildren are passed to a component using the Go context. To pass children to a component using Go code, use the `templ.WithChildren` function.\n\n```templ\npackage main\n\nimport (\n  \"context\"\n  \"os\"\n\n  \"github.com/a-h/templ\"\n)\n\ntempl wrapChildren() {\n\t<div id=\"wrapper\">\n\t\t{ children... }\n\t</div>\n}\n\nfunc main() {\n  contents := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n    _, err := io.WriteString(w, \"<div>Inserted from Go code</div>\")\n    return err\n  })\n  ctx := templ.WithChildren(context.Background(), contents)\n  wrapChildren().Render(ctx, os.Stdout)\n}\n```\n\n```html title=\"output\"\n<div id=\"wrapper\">\n <div>\n  Inserted from Go code\n </div>\n</div>\n```\n\nTo get children from the context, use the `templ.GetChildren` function.\n\n```templ\npackage main\n\nimport (\n  \"context\"\n  \"os\"\n\n  \"github.com/a-h/templ\"\n)\n\nfunc main() {\n  contents := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n    _, err := io.WriteString(w, \"<div>Inserted from Go code</div>\")\n    return err\n  })\n  wrapChildren := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n    children := templ.GetChildren(ctx)\n    ctx = templ.ClearChildren(ctx)\n    _, err := io.WriteString(w, \"<div id=\\\"wrapper\\\">\")\n    if err != nil {\n      return err\n    }\n    err = children.Render(ctx, w)\n    if err != nil {\n      return err\n    }\n    _, err = io.WriteString(w, \"</div>\")\n    return err\n  })\n```\n\n:::note\nThe `templ.ClearChildren` function is used to stop passing the children down the tree.\n:::\n\n## Components as parameters\n\nComponents can also be passed as parameters and rendered using the `@component` expression.\n\n```templ\npackage main\n\ntempl heading() {\n    <h1>Heading</h1>\n}\n\ntempl layout(contents templ.Component) {\n\t<div id=\"heading\">\n\t\t@heading()\n\t</div>\n\t<div id=\"contents\">\n\t\t@contents\n\t</div>\n}\n\ntempl paragraph(contents string) {\n\t<p>{ contents }</p>\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\tc := paragraph(\"Dynamic contents\")\n\tlayout(c).Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"output\"\n<div id=\"heading\">\n\t<h1>Heading</h1>\n</div>\n<div id=\"contents\">\n\t<p>Dynamic contents</p>\n</div>\n```\n\nYou can pass `templ` components as parameters to other components within templates using standard Go function call syntax.\n\n```templ\npackage main\n\ntempl heading() {\n    <h1>Heading</h1>\n}\n\ntempl layout(contents templ.Component) {\n\t<div id=\"heading\">\n\t\t@heading()\n\t</div>\n\t<div id=\"contents\">\n\t\t@contents\n\t</div>\n}\n\ntempl paragraph(contents string) {\n\t<p>{ contents }</p>\n}\n\ntempl root() {\n\t@layout(paragraph(\"Dynamic contents\"))\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\troot().Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"output\"\n<div id=\"heading\">\n\t<h1>Heading</h1>\n</div>\n<div id=\"contents\">\n\t<p>Dynamic contents</p>\n</div>\n```\n\n## Joining Components\n\nComponents can be aggregated into a single Component using `templ.Join`.\n\n```templ\npackage main\n\ntempl hello() {\n\t<span>hello</span>\n}\n\ntempl world() {\n\t<span>world</span>\n}\n\ntempl helloWorld() {\n\t@templ.Join(hello(), world())\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\thelloWorld().Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"output\"\n<span>hello</span><span>world</span>\n```\n\n## Sharing and re-using components\n\nSince templ components are compiled into Go functions by the `go generate` command, templ components follow the rules of Go, and are shared in exactly the same way as Go code.\n\ntempl files in the same directory can access each other's components. Components in different directories can be accessed by importing the package that contains the component, so long as the component is exported by capitalizing its name.\n\n:::tip\nIn Go, a _package_ is a collection of Go source files in the same directory that are compiled together. All of the functions, types, variables, and constants defined in one source file in a package are available to all other source files in the same package.\n\nPackages exist within a Go _module_, defined by the `go.mod` file.\n:::\n\n:::note\nGo is structured differently to JavaScript, but uses similar terminology. A single `.js` or `.ts` _file_ is like a Go package, and an NPM package is like a Go module.\n:::\n\n### Exporting components\n\nTo make a templ component available to other packages, export it by capitalizing its name.\n\n```templ\npackage components\n\ntempl Hello() {\n\t<div>Hello</div>\n}\n```\n\n### Importing components\n\nTo use a component in another package, import the package and use the component as you would any other Go function or type.\n\n```templ\npackage main\n\nimport \"github.com/a-h/templ/examples/counter/components\"\n\ntempl Home() {\n\t@components.Hello()\n}\n```\n\n:::tip\nTo import a component from another Go module, you must first import the module by using the `go get <module>` command. Then, you can import the component as you would any other Go package.\n:::\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/11-forms.md",
    "content": "# Forms and validation\n\nTo pass data from the client to the server without using JavaScript, you can use HTML forms to POST data.\n\ntempl can be used to create forms that submit data to the server. Depending on the design of your app, you can collect data from the form using JavaScript and submit it to an API from the frontend, or use a HTTP form submission to send the data to the server.\n\n## Hypermedia approach\n\ntempl isn't a framework, you're free to choose how you want to build your applications, but a common approach is to create a handler for each route, and then use templates to render the form and display validation errors.\n\nIn Go, the `net/http` package in the standard library provides a way to handle form submissions, and Gorilla `schema` can decode form data into Go structs. See https://github.com/gorilla/schema\n\n:::tip\nThe [Hypermedia Systems](https://hypermedia.systems/) book covers the main concepts of building web applications, without covering specific implementations. If you're new to web development, or have only ever used JavaScript frameworks, it may be worth reading the book to understand the approach.\n:::\n\n### Create a View Model\n\nThis view model should contain any data that is used by the form, including field values and any other state.\n\n```go\ntype Model struct {\n  Initial          bool\n  SubmitButtonText string\n\n  Name  string\n  Email string\n  Error string\n}\n```\n\nThe model can also include methods for validation, which will be used to check the data before saving it to the database.\n\n```go\nfunc (m *Model) ValidateName() (msgs []string) {\n  if m.Initial {\n    return\n  }\n  if m.Name == \"\" {\n    msgs = append(msgs, \"Name is required\")\n  }\n  return msgs\n}\n\nfunc (m *Model) NameHasError() bool {\n  return len(m.ValidateName()) > 0\n}\n\n// More validation methods...\n\nfunc (m *Model) Validate() (msgs []string) {\n  if m.Initial {\n    return\n  }\n  msgs = append(msgs, m.ValidateName()...)\n  msgs = append(msgs, m.ValidateEmail()...)\n  return msgs\n}\n```\n\n### Create a form template\n\nThe form should contain input fields for each piece of data in the model.\n\nIn the example code, the `name` and `email` input fields are populated with the values from the model.\n\nLater, we will use the Gorilla `schema` package to populate Go struct fields automatically from the form data when the form is submitted.\n\nIf a field value is invalid, the `has-error` class is added to the form group using the `templ.KV` function.\n\nTo protect your forms from cross-site request forgery (CSRF) attacks, use the [`gorilla/csrf`](https://github.com/gorilla/csrf) middleware to generate and validate CSRF tokens.\n\n```go\ncsrfKey := mustGenerateCSRFKey()\ncsrfMiddleware := csrf.Protect(csrfKey, csrf.TrustedOrigins([]string{\"localhost:8080\"}), csrf.FieldName(\"_csrf\"))\n```\n\nIn your form templates, include a hidden CSRF token field using a shared component:\n\n```templ\n<input type=\"hidden\" name=\"_csrf\" value={ ctx.Value(\"gorilla.csrf.Token\").(string) }/>\n```\n\nThis ensures all POST requests include a valid CSRF token.\n```templ\ntempl View(m Model) {\n  <h1>Add Contact</h1>\n  <ul>\n    <li><a href=\"/contacts\" hx-boost=\"true\">Back to Contacts</a></li>\n  </ul>\n  <form id=\"form\" method=\"post\" hx-boost=\"true\">\n    @csrf.CSRF()\n    <div id=\"name-group\" class={ \"form-group\", templ.KV(\"has-error\", m.NameHasError()) }>\n      <label for=\"name\">Name</label>\n      <input type=\"text\" id=\"name\" name=\"name\" class=\"form-control\" placeholder=\"Name\" value={ m.Name }/>\n    </div>\n    <div id=\"email-group\" class={ \"form-group\", templ.KV(\"has-error\", m.EmailHasError()) }>\n      <label for=\"email\">Email</label>\n      <input type=\"email\" id=\"email\" name=\"email\" class=\"form-control\" placeholder=\"Email\" value={ m.Email }/>\n    </div>\n    <div id=\"validation\">\n      if m.Error != \"\" {\n        <p class=\"error\">{ m.Error }</p>\n      }\n      if msgs := m.Validate(); len(msgs) > 0 {\n        @ValidationMessages(msgs)\n      }\n    </div>\n    <a href=\"/contacts\" class=\"btn btn-secondary\">Cancel</a>\n    <input type=\"submit\" value=\"Save\"/>\n  </form>\n}\n```\n\n### Display the form\n\nThe next step is to display the form to the user.\n\nOn `GET` requests, the form is displayed with an empty model for adding a new contact, or with an existing contact's data for editing.\n\n```go\nfunc (h *Handler) Get(w http.ResponseWriter, r *http.Request) {\n  model := NewModel()\n  // If it's an edit request, populate the model with existing data.\n  if id := r.PathValue(\"id\"); id != \"\" {\n    contact, ok, err := h.DB.Get(r.Context(), id)\n    if err != nil {\n      h.Log.Error(\"Failed to get contact\", slog.String(\"id\", id), slog.Any(\"error\", err))\n      http.Error(w, err.Error(), http.StatusInternalServerError)\n      return\n    }\n    if !ok {\n      http.Redirect(w, r, \"/contacts/edit\", http.StatusSeeOther)\n      return\n    }\n    model = ModelFromContact(contact)\n  }\n  h.DisplayForm(w, r, model)\n}\n```\n\n### Handle form submission\n\nWhen the form is submitted, the `POST` request is handled by parsing the form data and decoding it into the model using the Gorilla `schema` package.\n\nIf validation fails, the form is redisplayed with error messages.\n\n```go\nfunc (h *Handler) Post(w http.ResponseWriter, r *http.Request) {\n  // Parse the form.\n  err := r.ParseForm()\n  if err != nil {\n    http.Error(w, err.Error(), http.StatusBadRequest)\n    return\n  }\n\n  var model Model\n\n  // Decode the form.\n  dec := schema.NewDecoder()\n  dec.IgnoreUnknownKeys(true)\n  err = dec.Decode(&model, r.PostForm)\n  if err != nil {\n    h.Log.Warn(\"Failed to decode form\", slog.Any(\"error\", err))\n    http.Error(w, err.Error(), http.StatusBadRequest)\n    return\n  }\n\n  // Validate the input.\n  if len(model.Validate()) > 0 {\n    h.DisplayForm(w, r, model)\n    return\n  }\n\n  // Save the contact.\n  id := r.PathValue(\"id\")\n  if id == \"\" {\n    id = ksuid.New().String()\n  }\n  contact := db.NewContact(id, model.Name, model.Email)\n  if err = h.DB.Save(r.Context(), contact); err != nil {\n    h.Log.Error(\"Failed to save contact\", slog.String(\"id\", id), slog.Any(\"error\", err))\n    model.Error = \"Failed to save the contact. Please try again.\"\n    h.DisplayForm(w, r, model)\n    return\n  }\n\n  // Redirect back to the contact list.\n  http.Redirect(w, r, \"/contacts\", http.StatusSeeOther)\n}\n```\n\n## Example project\n\nThe `crud` project is a simple web application that allows users to manage contacts. It demonstrates how to handle forms, validation, and database interactions using Go's standard library and the Gorilla schema package.\n\nFor full example code, see `./examples/crud` in `github.com/a-h/templ`.\n\n- `main.go`: The entrypoint of the application.\n- `db`: Contains database logic, including models and database operations.\n- `routes`: Contains the HTTP handlers for different routes.\n- `layout`: Contains the common layout for all pages.\n- `static`: Contains static assets like CSS, JavaScript, and images.\n\n### Entrypoint\n\nThe `main.go` file is the entrypoint of the application.\n\nA common pattern in Go applications is to define a `run` function that can return an error to the main function.\n\n```go title=\"main.go\"\nvar dbURI = \"file:data.db?mode=rwc\"\nvar addr = \"localhost:8080\"\n\nfunc main() {\n  log := slog.Default()\n  ctx := context.Background()\n  if err := run(ctx, log); err != nil {\n    log.Error(\"Failed to run server\", slog.Any(\"error\", err))\n    os.Exit(1)\n  }\n}\n```\n\nThe `run` function first initializes the database connection.\n\n```go title=\"main.go\"\npool, err := sqlitex.NewPool(dbURI, sqlitex.PoolOptions{})\nif err != nil {\n    log.Error(\"Failed to open database\", slog.Any(\"error\", err))\n    return err\n}\nstore := sqlitekv.New(pool)\nif err := store.Init(ctx); err != nil {\n    log.Error(\"Failed to initialize store\", slog.Any(\"error\", err))\n    return err\n}\ndb := db.New(store)\n```\n\nNext, it sets up the HTTP server with routes for the home page, contacts listing, and contact management (add/edit/delete).\n\n```go title=\"main.go\"\nmux := http.NewServeMux()\n\nhomeHandler := home.NewHandler()\nmux.Handle(\"/\", homeHandler)\n\nch := contacts.NewHandler(log, db)\nmux.Handle(\"/contacts\", ch)\n\nceh := contactsedit.NewHandler(log, db)\nmux.Handle(\"/contacts/edit\", ceh)\nmux.Handle(\"/contacts/edit/{id}\", ceh)\n\ncdh := contactsdelete.NewHandler(log, db)\nmux.Handle(\"/contacts/delete/{id}\", cdh)\n```\n\nThe `static` directory contains scripts, CSS and images, and is served using Go's built in file serving handler.\n\n\n```go title=\"main.go\"\nmux.Handle(\"/static/\", http.StripPrefix(\"/static/\", http.FileServer(http.Dir(\"static\"))))\n```\n\nFinally, the server is started on the specified address and port.\n\n```go title=\"main.go\"\nlog.Info(\"Starting server\", slog.String(\"address\", addr))\nreturn http.ListenAndServe(addr, mux)\n```\n\n### Listing contacts\n\nThe route at `/contacts` renders a list of contacts, allowing users to view existing contacts and navigate to forms for adding, editing or deleting contacts.\n\nThe handler collects the list of contacts from the database, and passes it to the `View`, wrapping it all in `layout.Handler` so that the page is rendered with the common layout.\n\nIt's common practice to create a constructor function for the handler, and to define methods on the handler struct for each HTTP method that the handler supports to separate behaviour.\n\n```go title=\"routes/contacts/handler.go\"\nfunc NewHandler(log *slog.Logger, db *db.DB) http.Handler {\n  return &Handler{\n    Log: log,\n    DB:  db,\n  }\n}\n\ntype Handler struct {\n  Log *slog.Logger\n  DB  *db.DB\n}\n\nfunc (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n  switch r.Method {\n    case http.MethodGet:\n      h.Get(w, r)\n    default:\n      http.Error(w, \"Method not allowed\", http.StatusMethodNotAllowed)\n  }\n}\n```\n\nThe `Get` method retrieves the list of contacts from the database and passes it to the `View` template for rendering, using a standard layout.\n\n```go title=\"routes/contacts/handler.go\"\nfunc (h *Handler) Get(w http.ResponseWriter, r *http.Request) {\n  contacts, err := h.DB.List(r.Context())\n  if err != nil {\n    h.Log.Error(\"Failed to list contacts\", slog.Any(\"error\", err))\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n    return\n  }\n\n  v := layout.Handler(View(contacts))\n  v.ServeHTTP(w, r)\n}\n```\n\nThe view is a simple table containing a bit of logic to display \"No contacts\" if the list is empty, and links to edit or delete each contact.\n\nIt's common to break down a page into smaller components, so the `ContactsList` component is used to display the list of contacts, and is called from the `View` template.\n\n```templ title=\"routes/contacts/view.templ\"\ntempl View(contacts []db.Contact) {\n  <h1>Contacts</h1>\n  <ul>\n    <li><a href=\"/contacts/edit\" hx-boost=\"true\">Add contact</a></li>\n  </ul>\n  if len(contacts) == 0 {\n    <p>No contacts</p>\n  } else {\n    @ContactList(contacts)\n  }\n}\n\ntempl ContactList(contacts []db.Contact) {\n  <table class=\"table\">\n  <tr>\n    <th>\n      Name\n    </th>\n    <th>\n      Email\n    </th>\n    <th>\n      Actions\n    </th>\n  </tr>\n  for _, contact := range contacts {\n    <tr>\n      <td>{ contact.Name }</td>\n      <td>{ contact.Email }</td>\n      <td>\n        <a href={ fmt.Sprintf(\"/contacts/edit/%s\", url.PathEscape(contact.ID)) } hx-boost=\"true\">Edit</a>\n        <a href={ fmt.Sprintf(\"/contacts/delete/%s\", url.PathEscape(contact.ID)) } hx-boost=\"true\">Delete</a>\n      </td>\n    </tr>\n  }\n  </table>\n}\n```\n\n:::tip\nFor simple views, there's no need to create a view model (a struct that defines the data that will be displayed) and you can pass the data directly, but for more complex views or when you need to pass additional data to the template, it's usually clearer to define a view model.\n:::\n\n\n### Layout\n\nThe `layout` package provides a common structure for all pages, including links to static assets like CSS and JavaScript files.\n\nThe `content` component passed into the `Page` template is replaced with the specific content for each page. Multiple function arguments or structs can be passed to the `Page` template to enable multiple slots for content.\n\n```templ title=\"layout/page.templ\"\npackage layout\n\ntempl Page(content templ.Component) {\n  <!DOCTYPE html>\n  <html>\n    <head>\n      <script src=\"/static/htmx.min.js\"></script>\n      <link rel=\"stylesheet\" href=\"/static/bootstrap.css\"/>\n    </head>\n    <body class=\"container\">\n      @content\n    </body>\n  </html>\n}\n```\n\nA small helper function wraps the `Page` template to create an HTTP handler that can be used in routes.\n\n```go title=\"layout/layout.go\"\nfunc Handler(content templ.Component) http.Handler {\n  return templ.Handler(Page(content))\n}\n```\n\n### Adding and editing contacts\n\nThe `/contacts/edit` route is used for both adding a new contact and editing an existing one. The handler checks if an ID is provided in the URL to determine whether to create a new contact or edit an existing one.\n\nFor `Get` requests, the handler retrieves the contact if an ID is provided, or initializes a new model for adding a contact. The `DisplayForm` method renders the form using the `View` template.\n\n```go title=\"routes/contactsedit/handler.go\"\nfunc (h *Handler) Get(w http.ResponseWriter, r *http.Request) {\n  // Read the ID from the URL.\n  id := r.PathValue(\"id\")\n  model := NewModel()\n  if id != \"\" {\n    // Get the existing contact from the database and populate the form.\n    contact, ok, err := h.DB.Get(r.Context(), id)\n    if err != nil {\n      h.Log.Error(\"Failed to get contact\", slog.String(\"id\", id), slog.Any(\"error\", err))\n      http.Error(w, err.Error(), http.StatusInternalServerError)\n      return err\n    }\n    if !ok {\n      http.Redirect(w, r, \"/contacts/edit\", http.StatusSeeOther)\n      return\n    }\n    model = ModelFromContact(contact)\n  }\n  h.DisplayForm(w, r, model)\n}\n```\n\nNote that the `ModelFromContact` function is used to convert a `db.Contact` into a view model (`Model`) that can be used to populate the form fields.\n\n\nThe `DisplayForm` method handles rendering the form view and is used by both the `Get` and `Post` methods. It uses the `layout.Handler` to ensure that the form is rendered within the common layout of the application.\n\n```go title=\"routes/contactsedit/handler.go\"\nfunc (h *Handler) DisplayForm(w http.ResponseWriter, r *http.Request, m Model) {\n  layout.Handler(View(m)).ServeHTTP(w, r)\n}\n```\n\nFor `Post` requests, the handler parses the form data into the model, validates it, and saves the contact to the database. If validation fails, it redisplays the form with error messages.\n\n\n```go title=\"routes/contactsedit/handler.go\"\nfunc (h *Handler) Post(w http.ResponseWriter, r *http.Request) {\n  // Parse the form.\n  err := r.ParseForm()\n  if err != nil {\n    http.Error(w, err.Error(), http.StatusBadRequest)\n    return\n  }\n\n  var model Model\n\n  // Decode the form.\n  dec := schema.NewDecoder()\n  dec.IgnoreUnknownKeys(true)\n  err = dec.Decode(&model, r.PostForm)\n  if err != nil {\n    h.Log.Warn(\"Failed to decode form\", slog.Any(\"error\", err))\n    http.Error(w, err.Error(), http.StatusBadRequest)\n    return\n  }\n\n  // Validate the input.\n  if len(model.Validate()) > 0 {\n    h.DisplayForm(w, r, model)\n    return\n  }\n\n  // Save the contact.\n  id := r.PathValue(\"id\")\n  if id == \"\" {\n    id = ksuid.New().String()\n  }\n  contact := db.NewContact(id, model.Name, model.Email)\n  if err = h.DB.Save(r.Context(), contact); err != nil {\n    h.Log.Error(\"Failed to save contact\", slog.String(\"id\", id), slog.Any(\"error\", err))\n    model.Error = \"Failed to save the contact. Please try again.\"\n    h.DisplayForm(w, r, model)\n    return\n  }\n\n  // Redirect back to the contact list.\n  http.Redirect(w, r, \"/contacts\", http.StatusSeeOther)\n}\n```\n\nThe validation is carried out by a `Validate` method on the model, which checks for required fields and returns a list of errors if any are found. This allows for complex validation logic to be encapsulated within the model itself.\n\n```go title=./routes/contactsedit/model.go\nfunc NewModel() Model {\n  return Model{\n    Initial: true,\n  }\n}\n\nfunc ModelFromContact(contact db.Contact) (m Model) {\n  return Model{\n    Initial: true,\n    Name:    contact.Name,\n    Email:   contact.Email,\n  }\n}\n\ntype Model struct {\n  Initial          bool\n  SubmitButtonText string\n\n  Name  string\n  Email string\n  Error string\n}\n\nfunc (m *Model) ValidateName() (msgs []string) {\n  if m.Initial {\n    return\n  }\n  if m.Name == \"\" {\n    msgs = append(msgs, \"Name is required\")\n  }\n  return msgs\n}\n\nfunc (m *Model) NameHasError() bool {\n  return len(m.ValidateName()) > 0\n}\n\nfunc (m *Model) ValidateEmail() (msgs []string) {\n  if m.Initial {\n    return\n  }\n  if m.Email == \"\" {\n    return append(msgs, \"Email is required\")\n  }\n  if !strings.Contains(m.Email, \"@\") {\n    msgs = append(msgs, \"Email is invalid\")\n  }\n  return msgs\n}\n\nfunc (m *Model) EmailHasError() bool {\n  return len(m.ValidateEmail()) > 0\n}\n\nfunc (m *Model) Validate() (msgs []string) {\n  if m.Initial {\n    return\n  }\n  msgs = append(msgs, m.ValidateName()...)\n  msgs = append(msgs, m.ValidateEmail()...)\n  return msgs\n}\n```\n\nThe view for the contact form is defined in `view.templ`, which uses templ to render the form fields and any validation errors.\n\n```templ title=./routes/contact/sedit/view.templ\npackage contactsedit\n\ntempl View(m Model) {\n  <h1>Add Contact</h1>\n  <ul>\n    <li><a href=\"/contacts\" hx-boost=\"true\">Back to Contacts</a></li>\n  </ul>\n  <form id=\"form\" method=\"post\" hx-boost=\"true\">\n    <div id=\"name-group\" class={ \"form-group\", templ.KV(\"has-error\", m.NameHasError()) }>\n      <label for=\"name\">Name</label>\n      <input type=\"text\" id=\"name\" name=\"name\" class=\"form-control\" placeholder=\"Name\" value={ m.Name }/>\n    </div>\n    <div id=\"email-group\" class={ \"form-group\", templ.KV(\"has-error\", m.EmailHasError()) }>\n      <label for=\"email\">Email</label>\n      <input type=\"email\" id=\"email\" name=\"email\" class=\"form-control\" placeholder=\"Email\" value={ m.Email }/>\n    </div>\n    <div id=\"validation\">\n      if m.Error != \"\" {\n        <p class=\"error\">{ m.Error }</p>\n      }\n      if msgs := m.Validate(); len(msgs) > 0 {\n        @ValidationMessages(msgs)\n      }\n    </div>\n    <a href=\"/contacts\" class=\"btn btn-secondary\">Cancel</a>\n    <input type=\"submit\" value=\"Save\"/>\n  </form>\n}\n\ntempl ValidationMessages(msgs []string) {\n  if len(msgs) > 0 {\n    <div class=\"invalid-feedback\">\n      <ul>\n        for _, msg := range msgs {\n          <li class=\"error\">{ msg }</li>\n        }\n      </ul>\n    </div>\n  }\n}\n```\n\n:::note\nThe `hx-boost=\"true\"` attribute on the form enables htmx to handle the form submission via AJAX, allowing for a smoother user experience without full page reloads.\n:::\n\n### Deleting a contact\n\nThe `/contacts/delete/{id}` route handles the deletion of a contact. The handler retrieves the contact by ID and displays a confirmation form.\n\nAfter the user confirms the deletion, the contact is removed from the database and the user is redirected back to the contact list.\n\n```go title=./routes/contactsdelete/handler.go\ntype Handler struct {\n  Log *slog.Logger\n  DB  *db.DB\n}\n\nfunc (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n  switch r.Method {\n  case http.MethodGet:\n    h.Get(w, r)\n  case http.MethodPost:\n    h.Post(w, r)\n  default:\n    http.Error(w, \"Method not allowed\", http.StatusMethodNotAllowed)\n  }\n}\n\nfunc NewModel(name string) Model {\n  return Model{\n    Name: name,\n  }\n}\n\ntype Model struct {\n  Name string\n}\n\nfunc (h *Handler) Get(w http.ResponseWriter, r *http.Request) {\n  // Read the ID from the URL.\n  id := r.PathValue(\"id\")\n  if id == \"\" {\n    http.Redirect(w, r, \"/contacts\", http.StatusSeeOther)\n    return\n  }\n  // Get the existing contact from the database.\n  contact, ok, err := h.DB.Get(r.Context(), id)\n  if err != nil {\n    h.Log.Error(\"Failed to get contact\", slog.String(\"id\", id), slog.Any(\"error\", err))\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n    return\n  }\n  if !ok {\n    http.Redirect(w, r, \"/contacts\", http.StatusSeeOther)\n    return\n  }\n  h.DisplayForm(w, r, NewModel(contact.Name))\n}\n\nfunc (h *Handler) DisplayForm(w http.ResponseWriter, r *http.Request, m Model) {\n  layout.Handler(View(m)).ServeHTTP(w, r)\n}\n\nfunc (h *Handler) Post(w http.ResponseWriter, r *http.Request) {\n  id := r.PathValue(\"id\")\n  if id == \"\" {\n    http.Redirect(w, r, \"/contacts\", http.StatusSeeOther)\n    return\n  }\n\n  // Delete the contact from the database.\n  err := h.DB.Delete(r.Context(), id)\n  if err != nil {\n    h.Log.Error(\"Failed to delete contact\", slog.String(\"id\", id), slog.Any(\"error\", err))\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n    return\n  }\n\n  // Redirect back to the contact list.\n  http.Redirect(w, r, \"/contacts\", http.StatusSeeOther)\n}\n```\n\nThe view for the delete confirmation is straightforward, displaying the contact's name and asking for confirmation before deletion.\n\n```templ title=./routes/contactsdelete/view.templ\ntempl View(m Model) {\n  <h1>Delete</h1>\n  <p>\n    Are you sure you want to delete <strong>{ m.Name }</strong>?\n  </p>\n  <form id=\"form\" method=\"post\" hx-boost=\"true\">\n    @csrf.CSRF()\n    <a href=\"/contacts\" class=\"btn btn-secondary\">Cancel</a>\n    <input type=\"submit\" value=\"Delete\"/>\n  </form>\n}\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/12-css-style-management.md",
    "content": "# CSS style management\n\n## HTML class and style attributes\n\nThe standard HTML `class` and `style` attributes can be added to components. Note the use of standard quotes to denote a static value.\n\n```templ\ntempl button(text string) {\n\t<button class=\"button is-primary\" style=\"background-color: red\">{ text }</button>\n}\n```\n\n```html title=\"Output\"\n<button class=\"button is-primary\" style=\"background-color: red\">\n Click me\n</button>\n```\n\n## Style attribute\n\nTo use a variable in the style attribute, use braces to denote the Go expression.\n\n```templ\ntempl button(style, text string) {\n\t<button style={ style }>{ text }</button>\n}\n```\n\nYou can pass multiple values to the `style` attribute. The results are all added to the output.\n\n```templ\ntempl button(style1, style2 string, text string) {\n\t<button style={ style1, style2 }>{ text }</button>\n}\n```\n\nThe style attribute supports use of the following types:\n\n* `string` - A string containing CSS properties, e.g. `background-color: red`.\n* `templ.SafeCSS` - A value containing CSS properties and values that will not be sanitized, e.g. `background-color: red; text-decoration: underline`\n* `map[string]string` - A map of string keys to string values, e.g. `map[string]string{\"color\": \"red\"}`\n* `map[string]templ.SafeCSSProperty` - A map of string keys to values, where the values will not be sanitized.\n* `templ.KeyValue[string, string]` - A single CSS key/value.\n* `templ.KeyValue[string, templ.SafeCSSProperty` - A CSS key/value, but the value will not be sanitized.\n* `templ.KeyValue[string, bool]` - A map where the CSS in the key is only included in the output if the boolean value is true.\n* `templ.KeyValue[templ.SafeCSS, bool]` - A map where the CSS in the key is only included if the boolean value is true.\n\nFinally, a function value that returns any of the above types can be used.\n\nGo syntax allows you to pass a single function that returns a value and an error.\n\n```templ\ntempl Page(userType string) {\n\t<div style={ getStyle(userType) }>Styled</div>\n}\n\nfunc getStyle(userType string) (string, error) {\n   //TODO: Look up in something that might error.\n   return \"background-color: red\", errors.New(\"failed\")\n}\n```\n\nOr multiple functions and values that return a single type.\n\n```templ\ntempl Page(userType string) {\n\t<div style={ getStyle(userType), \"color: blue\" }>Styled</div>\n}\n\nfunc getStyle(userType string) (string) {\n   return \"background-color: red\"\n}\n```\n\n### Style attribute examples\n\n#### Maps\n\nMaps are useful when styles need to be dynamically computed based on component state or external inputs.\n\n```templ\nfunc getProgressStyle(percent int) map[string]string {\n    return map[string]string{\n        \"width\": fmt.Sprintf(\"%d%%\", percent),\n        \"transition\": \"width 0.3s ease\",\n    }\n}\n\ntempl ProgressBar(percent int) {\n    <div style={ getProgressStyle(percent) } class=\"progress-bar\">\n        <div class=\"progress-fill\"></div>\n    </div>\n}\n```\n\n```html title=\"Output (percent=75)\"\n<div style=\"transition:width 0.3s ease;width:75%;\" class=\"progress-bar\">\n    <div class=\"progress-fill\"></div>\n</div>\n```\n\n#### KeyValue pattern\n\nThe `templ.KV` helper provides conditional style application in a more compact syntax.\n\n```templ\ntempl TextInput(value string, hasError bool) {\n    <input\n        type=\"text\"\n        value={ value }\n        style={\n            templ.KV(\"border-color: #ff3860\", hasError),\n            templ.KV(\"background-color: #fff5f7\", hasError),\n            \"padding: 0.5em 1em;\",\n        }\n    >\n}\n```\n\n```html title=\"Output (hasError=true)\"\n<input \n    type=\"text\" \n    value=\"\" \n    style=\"border-color: #ff3860; background-color: #fff5f7; padding: 0.5em 1em;\">\n```\n\n#### Bypassing sanitization\n\nBy default, dynamic CSS values are sanitized to protect against dangerous CSS values that might introduce vulnerabilities into your application.\n\nHowever, if you're sure, you can bypass sanitization by marking your content as safe with the `templ.SafeCSS` and `templ.SafeCSSProperty` types.\n\n```templ\nfunc calculatePositionStyles(x, y int) templ.SafeCSS {\n    return templ.SafeCSS(fmt.Sprintf(\n        \"transform: translate(%dpx, %dpx);\",\n        x*2,  // Example calculation\n        y*2,\n    ))\n}\n\ntempl DraggableElement(x, y int) {\n    <div style={ calculatePositionStyles(x, y) }>\n        Drag me\n    </div>\n}\n```\n\n```html title=\"Output (x=10, y=20)\"\n<div style=\"transform: translate(20px, 40px);\">\n    Drag me\n</div>\n```\n\n### Pattern use cases\n\n| Pattern | Best For | Example Use Case |\n|---------|----------|------------------|\n| **Maps** | Dynamic style sets requiring multiple computed values | Progress indicators, theme switching |\n| **KeyValue** | Conditional style toggling | Form validation, interactive states |\n| **Functions** | Complex style generation | Animations, data visualizations |\n| **Direct Strings** | Simple static styles | Basic formatting, utility classes |\n\n### Sanitization behaviour\n\nBy default, dynamic CSS values are sanitized to protect against dangerous CSS values that might introduce vulnerabilities into your application.\n\n```templ\ntempl UnsafeExample() {\n    <div style={ \"background-image: url('javascript:alert(1)')\" }>\n        Dangerous content\n    </div>\n}\n```\n\n```html title=\"Output\"\n<div style=\"background-image:zTemplUnsafeCSSPropertyValue;\">\n    Dangerous content\n</div>\n```\n\nThese protections can be bypassed with the `templ.SafeCSS` and `templ.SafeCSSProperty` types.\n\n```templ\ntempl SafeEmbed() {\n    <div style={ templ.SafeCSS(\"background-image: url(/safe.png);\") }>\n        Trusted content\n    </div>\n}\n```\n\n```html title=\"Output\"\n<div style=\"background-image: url(/safe.png);\">\n    Trusted content\n</div>\n```\n\n:::note\nHTML attribute escaping is not bypassed, so `<`, `>`, `&` and quotes will always appear as HTML entities (`&lt;` etc.) in attributes - this is good practice, and doesn't affect how browsers use the CSS.\n:::\n\n### Error Handling\n\nInvalid values are automatically sanitized:\n\n```templ\ntempl InvalidButton() {\n    <button style={ \n        map[string]string{\n            \"\": \"invalid-property\",\n            \"color\": \"</style>\",\n        }\n    }>Click me</button>\n}\n```\n\n```html title=\"Output\"\n<button style=\"zTemplUnsafeCSSPropertyName:zTemplUnsafeCSSPropertyValue;color:zTemplUnsafeCSSPropertyValue;\">\n    Click me\n</button>\n```\n\nGo's type system doesn't support union types, so it's not possible to limit the inputs to the style attribute to just the supported types.\n\nAs such, the attribute takes `any`, and executes type checks at runtime. Any invalid types will produce the CSS value `zTemplUnsupportedStyleAttributeValue:Invalid;`.\n\n## Class attributes\n\nTo use a variable as the name of a CSS class, use a CSS expression.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl button(text string, className string) {\n\t<button class={ className }>{ text }</button>\n}\n```\n\nThe class expression can take an array of values.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl button(text string, className string) {\n\t<button class={ \"button\", className }>{ text }</button>\n}\n```\n\n### Dynamic class names\n\nToggle addition of CSS classes to an element based on a boolean value by passing:\n\n* A `string` containing the name of a class to apply.\n* A `templ.KV` value containing the name of the class to add to the element, and a boolean that determines whether the class is added to the attribute at render time.\n  * `templ.KV(\"is-primary\", true)`\n  * `templ.KV(\"hover:red\", true)`\n* A map of string class names to a boolean that determines if the class is added to the class attribute value at render time:\n  * `map[string]bool`\n  * `map[CSSClass]bool`\n\n```templ title=\"component.templ\"\npackage main\n\ncss red() {\n\tbackground-color: #ff0000;\n}\n\ntempl button(text string, isPrimary bool) {\n\t<button class={ \"button\", templ.KV(\"is-primary\", isPrimary), templ.KV(red(), isPrimary) }>{ text }</button>\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n)\n\nfunc main() {\n\tbutton(\"Click me\", false).Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<button class=\"button\">\n Click me\n</button>\n```\n\n## CSS elements\n\nThe standard `<style>` element can be used within a template.\n\n`<style>` element contents are rendered to the output without any changes.\n\n```templ\ntempl page() {\n\t<style type=\"text/css\">\n\t\tp {\n\t\t\tfont-family: sans-serif;\n\t\t}\n\t\t.button {\n\t\t\tbackground-color: black;\n\t\t\tforeground-color: white;\n\t\t}\n\t</style>\n\t<p>\n\t\tParagraph contents.\n\t</p>\n}\n```\n\n```html title=\"Output\"\n<style type=\"text/css\">\n\tp {\n\t\tfont-family: sans-serif;\n\t}\n\t.button {\n\t\tbackground-color: black;\n\t\tforeground-color: white;\n\t}\n</style>\n<p>\n\tParagraph contents.\n</p>\n```\n\n:::tip\nIf you want to make sure that the CSS element is only output once, even if you use a template many times, use a CSS expression.\n:::\n\n## CSS components\n\nWhen developing a component library, it may not be desirable to require that specific CSS classes are present when the HTML is rendered.\n\nThere may be CSS class name clashes, or developers may forget to include the required CSS.\n\nTo include CSS within a component library, use a CSS component.\n\nCSS components can also be conditionally rendered.\n\n```templ title=\"component.templ\"\npackage main\n\nvar red = \"#ff0000\"\nvar blue = \"#0000ff\"\n\ncss primaryClassName() {\n\tbackground-color: #ffffff;\n\tcolor: { red };\n}\n\ncss className() {\n\tbackground-color: #ffffff;\n\tcolor: { blue };\n}\n\ntempl button(text string, isPrimary bool) {\n\t<button class={ \"button\", className(), templ.KV(primaryClassName(), isPrimary) }>{ text }</button>\n}\n```\n\n```html title=\"Output\"\n<style type=\"text/css\">\n .className_f179{background-color:#ffffff;color:#ff0000;}\n</style>\n<button class=\"button className_f179\">\n Click me\n</button>\n```\n\n:::info\nThe CSS class is given a unique name the first time it is used, and only rendered once per HTTP request to save bandwidth.\n:::\n\n:::caution\nThe class name is autogenerated, don't rely on it being consistent.\n:::\n\n### CSS component arguments\n\nCSS components can also require function arguments.\n\n```templ title=\"component.templ\"\npackage main\n\ncss loading(percent int) {\n\twidth: { fmt.Sprintf(\"%d%%\", percent) };\n}\n\ntempl index() {\n    <div class={ loading(50) }></div>\n    <div class={ loading(100) }></div>\n}\n```\n\n```html title=\"Output\"\n<style type=\"text/css\">\n .loading_a3cc{width:50%;}\n</style>\n<div class=\"loading_a3cc\"></div>\n<style type=\"text/css\">\n .loading_9ccc{width:100%;}\n</style>\n<div class=\"loading_9ccc\"></div>\n```\n\n### CSS Sanitization\n\nTo prevent CSS injection attacks, templ automatically sanitizes dynamic CSS property names and values using the `templ.SanitizeCSS` function. Internally, this uses a lightweight fork of Google's `safehtml` package to sanitize the value.\n\nIf a property name or value has been sanitized, it will be replaced with `zTemplUnsafeCSSPropertyName` for property names, or `zTemplUnsafeCSSPropertyValue` for property values.\n\nTo bypass this sanitization, e.g. for URL values of `background-image`, you can mark the value as safe using the `templ.SafeCSSProperty` type.\n\n```templ\ncss windVaneRotation(degrees float64) {\n\ttransform: { templ.SafeCSSProperty(fmt.Sprintf(\"rotate(%ddeg)\", int(math.Round(degrees)))) };\n}\n\ntempl Rotate(degrees float64) {\n\t<div class={ windVaneRotation(degrees) }>Rotate</div>\n}\n```\n\n### CSS Middleware\n\nThe use of CSS templates means that `<style>` elements containing the CSS are rendered on each HTTP request.\n\nTo save bandwidth, templ can provide a global stylesheet that includes the output of CSS templates instead of including `<style>` tags in each HTTP request.\n\nTo provide a global stylesheet, use templ's CSS middleware, and register templ classes on application startup.\n\nThe middleware adds a HTTP route to the web server (`/styles/templ.css` by default) that renders the `text/css` classes that would otherwise be added to `<style>` tags when components are rendered. \n\nFor example, to stop the `className` CSS class from being added to the output, the HTTP middleware can be used.\n\n```go\nc1 := className()\nhandler := NewCSSMiddleware(httpRoutes, c1)\nhttp.ListenAndServe(\":8000\", handler)\n```\n\n:::caution\nDon't forget to add a `<link rel=\"stylesheet\" href=\"/styles/templ.css\">` to your HTML to include the generated CSS class names!\n:::\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/13-script-templates.md",
    "content": "# Using JavaScript with templ\n\n## Script tags\n\nUse standard `<script>` tags, and standard HTML attributes to run JavaScript on the client.\n\n```templ\ntempl body() {\n  <script>\n    function handleClick(event) {\n      alert(event + ' clicked');\n    }\n  </script>\n  <button onclick=\"handleClick(this)\">Click me</button>\n}\n```\n\nIf you have `prettierd`, `prettier` or `npx` on your `PATH`, `templ` will use it to format the `<script>` tag contents.\n\n:::tip\nTo ensure that a `<script>` tag within a templ component is only rendered once per HTTP response (or context), use a [templ.OnceHandle](18-render-once.md).\n\nUsing a `templ.OnceHandle` allows a component to define global client-side scripts that it needs to run without including the scripts multiple times in the response.\n:::\n\n## Pass Go data to JavaScript\n\n### Pass Go data to a JavaScript event handler\n\nUse `templ.JSFuncCall` to pass server-side data to client-side scripts by calling a JavaScript function.\n\n```templ title=\"input.templ\"\ntempl Component(data CustomType) {\n\t<button onclick={ templ.JSFuncCall(\"alert\", data.Message) }>Show alert</button>\n}\n```\n\nThe data passed to the `alert` function is JSON encoded, so if `data.Message` was the string value of `Hello, from the JSFuncCall data`, the output would be:\n\n```html title=\"output.html\"\n<button onclick=\"alert('Hello, from the JSFuncCall data')\">Show alert</button>\n```\n\n### Pass event objects to an Event Handler\n\nHTML element `on*` attributes pass an event object to the function. To pass the event object to a function, use `templ.JSExpression`.\n\n\n:::warning\n`templ.JSExpression` bypasses JSON encoding, so the string value is output directly to the HTML - this can be a security risk if the data is not trusted, e.g. the data is user input, not a compile-time constant.\n:::\n\n```templ title=\"input.templ\"\n<script>\n\tfunction clickHandler(event, message) {\n\t\talert(message);\n\t\tevent.preventDefault();\n\t}\n</script>\n<button onclick={ templ.JSFuncCall(\"clickHandler\", templ.JSExpression(\"event\"), \"message from Go\") }>Show event</button>\n```\n\nThe output would be:\n\n```html title=\"output.html\"\n<script>\n\tfunction clickHandler(event, message) {\n\t\talert(message);\n\t\tevent.preventDefault();\n\t}\n</script>\n<button onclick=\"clickHandler(event, 'message from Go')\">Show event</button>\n```\n\n### Call client side functions with server side data\n\nUse `templ.JSFuncCall` to call a client-side function with server-side data.\n\n`templ.JSFuncCall` takes a function name and a variadic list of arguments. The arguments are JSON encoded and passed to the function.\n\nIn the case that the function name is invalid (e.g. contains `</script>` or is a JavaScript expression, not a function name), the function name will be sanitized to `__templ_invalid_function_name`.\n\n```templ title=\"components.templ\"\ntempl InitializeClientSideScripts(data CustomType) {\n  @templ.JSFuncCall(\"functionToCall\", data.Name, data.Age)\n}\n```\n\nThis will output a `<script>` tag that calls the `functionToCall` function with the `Name` and `Age` properties of the `data` object.\n\n```html title=\"output.html\"\n<script>\n  functionToCall(\"John\", 42);\n</script>\n```\n\n:::tip\nIf you want to write out an arbitrary string containing JavaScript, and are sure it is safe, you can use `templ.JSUnsafeFuncCall` to bypass script sanitization.\n\nWhatever string you pass to `templ.JSUnsafeFuncCall` will be output directly to the HTML, so be sure to validate the input.\n:::\n\n### Pass server-side data to the client in a HTML attribute\n\nA common approach used by libraries like alpine.js is to pass data to the client in a HTML attribute.\n\nTo pass server-side data to the client in a HTML attribute, use `templ.JSONString` to encode the data as a JSON string.\n\n```templ title=\"input.templ\"\ntempl body(data any) {\n  <button id=\"alerter\" alert-data={ templ.JSONString(data) }>Show alert</button>\n}\n```\n\n```html title=\"output.html\"\n<button id=\"alerter\" alert-data=\"{&quot;msg&quot;:&quot;Hello, from the attribute data&quot;}\">Show alert</button>\n```\n\nThe data in the attribute can then be accessed from client-side JavaScript.\n\n```javascript\nconst button = document.getElementById('alerter');\nconst data = JSON.parse(button.getAttribute('alert-data'));\n```\n\n[alpine.js](https://alpinejs.dev/) uses `x-*` attributes to pass data to the client:\n\n```templ\ntempl DataDisplay(data DataType) {\n  <div x-data={ templ.JSONString(data) }>\n      ...\n  </div>\n}\n```\n\n### Pass server-side data to the client in a script element\n\nIn addition to passing data in HTML attributes, you can also pass data to the client in a `<script>` element.\n\n```templ title=\"input.templ\"\ntempl body(data any) {\n  @templ.JSONScript(\"id\", data)\n}\n```\n\n```html title=\"output.html\"\n<script id=\"id\" type=\"application/json\">{\"msg\":\"Hello, from the script data\"}</script>\n```\n\nThe data in the script tag can then be accessed from client-side JavaScript.\n\n```javascript\nconst data = JSON.parse(document.getElementById('id').textContent);\n```\n\n### Interpolate Go data within JavaScript code in a script tag\n\nIf you want to use Go data as variables within JavaScript, you can use a `{{ value }}` block to place Go data within the script.\n\ntempl will automatically escape the Go data to prevent XSS attacks.\n\nWithin strings, you can use `{{ value }}` to interpolate Go data.\n\n```templ title=\"input.templ\"\ntempl body(msg string) {\n  <script>\n    const message = \"Your message: {{ msg }}\";\n    alert(message);\n  </script>\n}\n```\n\nThe output would be:\n\n```html title=\"output.html\" msg=\"Hello\"\n<script>\n  const message = \"Your message: Hello\";\n  alert(message);\n</script>\n```\n\nOutside JavaScript strings, data is JSON encoded so that it can be used as a JavaScript object.\n\n```templ title=\"input.templ\"\ntempl body(msg string) {\n  <script>\n    const message = {{ msg }};\n    alert(message);\n  </script>\n}\n```\n\nThe output would be:\n\n```html title=\"output.html\" msg=\"Hello\"\n<script>\n  const message = \"Hello\";\n  alert(message);\n</script>\n```\n\n:::tip\nIt's better to pass data to the client in a HTML attribute or a script tag, as this separates the data from the JavaScript code, making it easier to maintain and debug.\n:::\n\n## Avoiding inline event handlers\n\nAccording to Mozilla, [inline event handlers are considered bad practice](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Scripting/Events#inline_event_handlers_%E2%80%94_dont_use_these).\n\nThis example demonstrates how to add client-side behaviour to a component using a script tag.\n\nThe example uses a `templ.OnceHandle` to define global client-side scripts that are required, without rendering the scripts multiple times in the response.\n\n```templ title=\"component.templ\"\npackage main\n\nimport \"net/http\"\n\nvar helloHandle = templ.NewOnceHandle()\n\ntempl hello(label, name string) {\n  // This script is only rendered once per HTTP request.\n  @helloHandle.Once() {\n    <script>\n      function hello(name) {\n        alert('Hello, ' + name + '!');\n      }\n    </script>\n  }\n  <div>\n    <input type=\"button\" value={ label } data-name={ name }/>\n    <script>\n      // To prevent the variables from leaking into the global scope,\n      // this script is wrapped in an IIFE (Immediately Invoked Function Expression).\n      (() => {\n        let scriptElement = document.currentScript;\n        let parent = scriptElement.closest('div');\n        let nearestButtonWithName = parent.querySelector('input[data-name]');\n        nearestButtonWithName.addEventListener('click', function() {\n          let name = nearestButtonWithName.getAttribute('data-name');\n          hello(name);\n        })\n      })()\n    </script>\n  </div>\n}\n\ntempl page() {\n  @hello(\"Hello User\", \"user\")\n  @hello(\"Hello World\", \"world\")\n}\n\nfunc main() {\n  http.Handle(\"/\", templ.Handler(page()))\n  http.ListenAndServe(\"127.0.0.1:8080\", nil)\n}\n```\n\n:::tip\nYou might find libraries like [surreal](https://github.com/gnat/surreal) useful for reducing boilerplate.\n\n```templ\nvar helloHandle = templ.NewOnceHandle()\nvar surrealHandle = templ.NewOnceHandle()\n\ntempl hello(label, name string) {\n  @helloHandle.Once() {\n    <script>\n      function hello(name) {\n        alert('Hello, ' + name + '!');\n      }\n    </script>\n  }\n  @surrealHandle.Once() {\n    <script src=\"https://cdn.jsdelivr.net/gh/gnat/surreal@3b4572dd0938ce975225ee598a1e7381cb64ffd8/surreal.js\"></script>\n  }\n  <div>\n    <input type=\"button\" value={ label } data-name={ name }/>\n    <script>\n      // me(\"-\") returns the previous sibling element.\n      me(\"-\").addEventListener('click', function() {\n        let name = this.getAttribute('data-name');\n        hello(name);\n      })\n    </script>\n  </div>\n}\n```\n:::\n\n## Importing scripts\n\nUse standard `<script>` tags to load JavaScript from a URL.\n\n```templ\ntempl head() {\n\t<head>\n\t\t<script src=\"https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js\"></script>\n\t</head>\n}\n```\n\nAnd use the imported JavaScript directly in templ via `<script>` tags.\n\n```templ\ntempl body() {\n\t<script>\n\t\tconst chart = LightweightCharts.createChart(document.body, { width: 400, height: 300 });\n\t\tconst lineSeries = chart.addLineSeries();\n\t\tlineSeries.setData([\n\t\t\t\t{ time: '2019-04-11', value: 80.01 },\n\t\t\t\t{ time: '2019-04-12', value: 96.63 },\n\t\t\t\t{ time: '2019-04-13', value: 76.64 },\n\t\t\t\t{ time: '2019-04-14', value: 81.89 },\n\t\t\t\t{ time: '2019-04-15', value: 74.43 },\n\t\t\t\t{ time: '2019-04-16', value: 80.01 },\n\t\t\t\t{ time: '2019-04-17', value: 96.63 },\n\t\t\t\t{ time: '2019-04-18', value: 76.64 },\n\t\t\t\t{ time: '2019-04-19', value: 81.89 },\n\t\t\t\t{ time: '2019-04-20', value: 74.43 },\n\t\t]);\n\t</script>\n}\n```\n\n:::tip\nYou can use a CDN to serve 3rd party scripts, or serve your own and 3rd party scripts from your server using a `http.FileServer`.\n\n```go\nmux := http.NewServeMux()\nmux.Handle(\"/assets/\", http.StripPrefix(\"/assets/\", http.FileServer(http.Dir(\"assets\"))))\nhttp.ListenAndServe(\"localhost:8080\", mux)\n```\n:::\n\n## Working with NPM projects\n\nhttps://github.com/a-h/templ/tree/main/examples/typescript contains a TypeScript example that uses `esbuild` to transpile TypeScript into plain JavaScript, along with any required `npm` modules.\n\nAfter transpilation and bundling, the output JavaScript code can be used in a web page by including a `<script>` tag.\n\n### Creating a TypeScript project\n\nCreate a new TypeScript project with `npm`, and install TypeScript and `esbuild` as development dependencies.\n\n```bash\nmkdir ts\ncd ts\nnpm init\nnpm install --save-dev typescript esbuild\n```\n\nCreate a `src` directory to hold the TypeScript code.\n\n```bash\nmkdir src\n```\n\nAnd add a TypeScript file to the `src` directory.\n\n```typescript title=\"ts/src/index.ts\"\nfunction hello() {\n  console.log('Hello, from TypeScript');\n}\n```\n\n### Bundling TypeScript code\n\nAdd a script to build the TypeScript code in `index.ts` and copy it to an output directory (in this case `./assets/js/index.js`).\n\n```json title=\"ts/package.json\"\n{\n  \"name\": \"ts\",\n  \"version\": \"1.0.0\",\n  \"scripts\": {\n    \"build\": \"esbuild --bundle --minify --outfile=../assets/js/index.js ./src/index.ts\"\n  },\n  \"devDependencies\": {\n    \"esbuild\": \"0.21.3\",\n    \"typescript\": \"^5.4.5\"\n  }\n}\n```\n\nAfter running `npm build` in the `ts` directory, the TypeScript code is transpiled into JavaScript and copied to the output directory.\n\n### Using the output JavaScript\n\nThe output file `../assets/js/index.js` can then be used in a templ project.\n\n```templ title=\"components/head.templ\"\ntempl head() {\n\t<head>\n\t\t<script src=\"/assets/js/index.js\"></script>\n\t</head>\n}\n```\n\nYou will need to configure your Go web server to serve the static content.\n\n```go title=\"main.go\"\nfunc main() {\n\tmux := http.NewServeMux()\n\t// Serve the JS bundle.\n\tmux.Handle(\"/assets/\", http.StripPrefix(\"/assets/\", http.FileServer(http.Dir(\"assets\"))))\n\n\t// Serve components.\n\tdata := map[string]any{\"msg\": \"Hello, World!\"}\n\th := templ.Handler(components.Page(data))\n\tmux.Handle(\"/\", h)\n\n\tfmt.Println(\"Listening on http://localhost:8080\")\n\thttp.ListenAndServe(\"localhost:8080\", mux)\n}\n```\n\n## Script templates\n\n:::warning\nScript templates are a legacy feature and are not recommended for new projects.\n\nUse the `templ.JSFuncCall`, `templ.JSONString` and other features of templ alongside standard `<script>` tags to import standalone JavaScript files, optionally created by a bundler like `esbuild`.\n:::\n\nIf you need to pass Go data to scripts, you can use a script template.\n\nHere, the `page` HTML template includes a `script` element that loads a charting library, which is then used by the `body` element to render some data.\n\n```templ\npackage main\n\nscript graph(data []TimeValue) {\n\tconst chart = LightweightCharts.createChart(document.body, { width: 400, height: 300 });\n\tconst lineSeries = chart.addLineSeries();\n\tlineSeries.setData(data);\n}\n\ntempl page(data []TimeValue) {\n\t<html>\n\t\t<head>\n\t\t\t<script src=\"https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js\"></script>\n\t\t</head>\n\t\t<body onload={ graph(data) }></body>\n\t</html>\n}\n```\n\nThe data is loaded by the backend into the template. This example uses a constant, but it could easily have collected the `[]TimeValue` from a database.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype TimeValue struct {\n\tTime  string  `json:\"time\"`\n\tValue float64 `json:\"value\"`\n}\n\nfunc main() {\n\tmux := http.NewServeMux()\n\n\t// Handle template.\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tdata := []TimeValue{\n\t\t\t{Time: \"2019-04-11\", Value: 80.01},\n\t\t\t{Time: \"2019-04-12\", Value: 96.63},\n\t\t\t{Time: \"2019-04-13\", Value: 76.64},\n\t\t\t{Time: \"2019-04-14\", Value: 81.89},\n\t\t\t{Time: \"2019-04-15\", Value: 74.43},\n\t\t\t{Time: \"2019-04-16\", Value: 80.01},\n\t\t\t{Time: \"2019-04-17\", Value: 96.63},\n\t\t\t{Time: \"2019-04-18\", Value: 76.64},\n\t\t\t{Time: \"2019-04-19\", Value: 81.89},\n\t\t\t{Time: \"2019-04-20\", Value: 74.43},\n\t\t}\n\t\tpage(data).Render(r.Context(), w)\n\t})\n\n\t// Start the server.\n\tfmt.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\":8080\", mux); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\n`script` elements are templ Components, so you can also directly render the Javascript function, passing in Go data, using the `@` expression:\n\n```templ\npackage main\n\nimport \"fmt\"\n\nscript printToConsole(content string) {\n\tconsole.log(content)\n}\n\ntempl page(content string) {\n\t<html>\n\t\t<body>\n\t\t  @printToConsole(content)\n\t\t  @printToConsole(fmt.Sprintf(\"Again: %s\", content))\n\t\t</body>\n\t</html>\n}\n```\n\nThe data passed into the Javascript function will be JSON encoded, which then can be used inside the function.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc main() {\n\tmux := http.NewServeMux()\n\n\t// Handle template.\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Format the current time and pass it into our template\n\t\tpage(time.Now().String()).Render(r.Context(), w)\n\t})\n\n\t// Start the server.\n\tfmt.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\":8080\", mux); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\nAfter building and running the executable, running `curl http://localhost:8080/` would render:\n\n```html title=\"Output\"\n<html>\n\t<body>\n\t\t<script>function __templ_printToConsole_5a85(content){console.log(content)}</script>\n\t\t<script>__templ_printToConsole_5a85(\"2023-11-11 01:01:40.983381358 +0000 UTC\")</script>\n\t\t<script>__templ_printToConsole_5a85(\"Again: 2023-11-11 01:01:40.983381358 +0000 UTC\")</script>\n\t</body>\n</html>\n```\n\nThe `JSExpression` type is used to pass arbitrary JavaScript expressions to a templ script template.\n\nA common use case is to pass the `event` or `this` objects to an event handler.\n\n```templ\npackage main\n\nscript showButtonWasClicked(event templ.JSExpression) {\n\tconst originalButtonText = event.target.innerText\n\tevent.target.innerText = \"I was Clicked!\"\n\tsetTimeout(() => event.target.innerText = originalButtonText, 2000)\n}\n\ntempl page() {\n\t<html>\n\t\t<body>\n\t\t\t<button type=\"button\" onclick={ showButtonWasClicked(templ.JSExpression(\"event\")) }>Click Me</button>\n\t\t</body>\n\t</html>\n}\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/14-comments.md",
    "content": "# Comments\n\n# HTML comments\n\nInside templ statements, use HTML comments.\n\n```templ title=\"template.templ\"\ntempl template() {\n\t<!-- Single line -->\n\t<!--\n\t\tSingle or multiline.\n\t-->\n}\n```\n\nComments are rendered to the template output.\n\n```html title=\"Output\"\n<!-- Single line -->\n<!--\n\tSingle or multiline.\n-->\n```\n\nAs per HTML, nested comments are not supported.\n\n# Go comments\n\nOutside of templ statements, use Go comments.\n\n```templ\npackage main\n\n// Use standard Go comments outside templ statements.\nvar greeting = \"Hello!\"\n\ntempl hello(name string) {\n\t<p>{greeting} { name }</p>\n}\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/15-context.md",
    "content": "# Context\n\n## What problems does `context` solve?\n\n### \"Prop drilling\"\n\nIt can be cumbersome to pass data from parents through to children components, since this means that every component in the hierarchy has to accept parameters and pass them through to children.\n\nThe technique of passing data through a stack of components is sometimes called \"prop drilling\".\n\nIn this example, the `middle` component doesn't use the `name` parameter, but must accept it as a parameter in order to pass it to the `bottom` component.\n\n```templ title=\"component.templ\"\npackage main\n\ntempl top(name string) {\n\t<div>\n\t\t@middle(name)\n\t</div>\n}\n\ntempl middle(name string) {\n\t<ul>\n\t\t@bottom(name)\n\t</ul>\n}\n\ntempl bottom(name string) {\n  <li>{ name }</li>\n}\n```\n\n:::tip\nIn many cases, prop drilling is the best way to pass data because it's simple and reliable.\n\nContext is not strongly typed, and errors only show at runtime, not compile time, so it should be used sparingly in your application.\n:::\n\n### Coupling\n\nSome data is useful for many components throughout the hierarchy, for example:\n\n* Whether the current user is logged in or not.\n* The username of the current user.\n* The locale of the user (used for localization).\n* Theme preferences (e.g. light vs dark).\n\nOne way to pass this information is to create a `Settings` struct and pass it through the stack as a parameter.\n\n```templ title=\"component.templ\"\npackage main\n\ntype Settings struct {\n\tUsername string\n\tLocale   string\n\tTheme    string\n}\n\ntempl top(settings Settings) {\n\t<div>\n\t\t@middle(settings)\n\t</div>\n}\n\ntempl middle(settings Settings) {\n\t<ul>\n\t\t@bottom(settings)\n\t</ul>\n}\n\ntempl bottom(settings Settings) {\n  <li>{ settings.Theme }</li>\n}\n```\n\nHowever, this `Settings` struct may be unique to a single website, and reduce the ability to reuse a component in another website, due to its tight coupling with the `Settings` struct.\n\n## Using `context`\n\n:::info\ntempl components have an implicit `ctx` variable within the scope. This `ctx` variable is the variable that is passed to the `templ.Component`'s `Render` method.\n:::\n\nTo allow data to be accessible at any level in the hierarchy, we can use Go's built in `context` package.\n\nWithin templ components, use the implicit `ctx` variable to access the context.\n\n```templ title=\"component.templ\"\ntempl themeName() {\n\t<div>{ ctx.Value(themeContextKey).(string) }</div>\n}\n```\n\nTo allow the template to get the `themeContextKey` from the context, create a context, and pass it to the component's `Render` function.\n\n```templ title=\"main.go\"\n// Define the context key type.\ntype contextKey string\n\n// Create a context key for the theme.\nvar themeContextKey contextKey = \"theme\"\n\n// Create a context variable that inherits from a parent, and sets the value \"test\".\nctx := context.WithValue(context.Background(), themeContextKey, \"test\")\n\n// Pass the ctx variable to the render function.\nthemeName().Render(ctx, w)\n```\n\n:::warning\nAttempting to access a context key that doesn't exist, or using an invalid type assertion will trigger a panic.\n:::\n\n### Tidying up\n\nRather than read from the context object directly, it's common to implement a type-safe function instead.\n\nThis is also required when the type of the context key is in a different package to the consumer of the context, and the type is private (which is usually the case).\n\n```templ title=\"main.go\"\nfunc GetTheme(ctx context.Context) string {\n\tif theme, ok := ctx.Value(themeContextKey).(string); ok {\n\t\treturn theme\n\t}\n\treturn \"\"\n}\n```\n\nThis minor change makes the template code a little tidier.\n\n```templ title=\"component.templ\"\ntempl themeName() {\n\t<div>{ GetTheme(ctx) }</div>\n}\n```\n\n:::note\nAs of v0.2.731, Go's built in `context` package is no longer implicitly imported into .templ files.\n:::\n\n## Using `context` with HTTP middleware\n\nIn HTTP applications, a common pattern is to insert HTTP middleware into the request/response chain.\n\nMiddleware can be used to update the context that is passed to other components. Common use cases for middleware include authentication, and theming.\n\nBy inserting HTTP middleware, you can set values in the context that can be read by any templ component in the stack for the duration of that HTTP request.\n\n```templ title=\"component.templ\"\ntype contextKey string\nvar contextClass = contextKey(\"class\")\n\nfunc Middleware(next http.Handler) http.Handler {\n  return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request ) {\n    ctx := context.WithValue(r.Context(), contextClass, \"red\")\n    next.ServeHTTP(w, r.WithContext(ctx))\n  })\n}\n\ntempl Page() {\n  @Show()\n}\n\ntempl Show() {\n  <div class={ ctx.Value(contextClass) }>Display</div>\n}\n\nfunc main() {\n  h := templ.Handler(Page())\n  withMiddleware := Middleware(h)\n  http.Handle(\"/\", withMiddleware)\n  http.ListenAndServe(\":8080\", nil)\n}\n```\n\n:::warning\nIf you write a component that relies on a context variable that doesn't exist, or is an unexpected type, your component will panic at runtime.\n\nThis means that if your component relies on HTTP middleware that sets the context, and you forget to add it, your component will panic at runtime.\n:::\n\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/16-using-with-go-templates.md",
    "content": "# Using with `html/template`\n\nTempl components can be used with the Go standard library [`html/template`](https://pkg.go.dev/html/template) package.\n\n## Using `html/template` in a templ component\n\nTo use an existing `html/template` in a templ component, use the `templ.FromGoHTML` function.\n\n```templ title=\"component.templ\"\npackage testgotemplates\n\nimport \"html/template\"\n\nvar goTemplate = template.Must(template.New(\"example\").Parse(\"<div>{{ . }}</div>\"))\n\ntempl Example() {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<body>\n\t\t\t@templ.FromGoHTML(goTemplate, \"Hello, World!\")\n\t\t</body>\n\t</html>\n}\n```\n\n```go title=\"main.go\"\nfunc main() {\n\tExample.Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<!DOCTYPE html>\n<html>\n\t<body>\n\t\t<div>Hello, World!</div>\n\t</body>\n</html>\n```\n\n## Using a templ component with\t`html/template`\n\nTo use a templ component within a `html/template`, use the `templ.ToGoHTML` function to render the component into a `template.HTML value`.\n\n```templ title=\"component.html\"\npackage testgotemplates\n\nimport \"html/template\"\n\nvar example = template.Must(template.New(\"example\").Parse(`<!DOCTYPE html>\n<html>\n\t<body>\n\t\t{{ . }}\n\t</body>\n</html>\n`))\n\ntempl greeting() {\n\t<div>Hello, World!</div>\n}\n```\n\n```go title=\"main.go\"\nfunc main() {\n\t// Create the templ component.\n\ttemplComponent := greeting()\n\n\t// Render the templ component to a `template.HTML` value.\n\thtml, err := templ.ToGoHTML(context.Background(), templComponent)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to convert to html: %v\", err)\n\t}\n\n\t// Use the `template.HTML` value within the text/html template.\n\terr = example.Execute(os.Stdout, html)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to execute template: %v\", err)\n\t}\n}\n```\n\n```html title=\"Output\"\n<!DOCTYPE html>\n<html>\n\t<body>\n\t\t<div>Hello, World!</div>\n\t</body>\n</html>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/17-rendering-raw-html.md",
    "content": "# Rendering raw HTML\n\nTo render HTML that has come from a trusted source, bypassing all HTML escaping and security mechanisms that templ includes, use the `templ.Raw` function.\n\n:::info\nOnly include HTML that comes from a trusted source.\n:::\n\n:::warning\nUse of this function may introduce security vulnerabilities to your program.\n:::\n\n```templ title=\"component.templ\"\ntempl Example() {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<body>\n\t\t\t@templ.Raw(\"<div>Hello, World!</div>\")\n\t\t</body>\n\t</html>\n}\n```\n\n```html title=\"Output\"\n<!DOCTYPE html>\n<html>\n\t<body>\n\t\t<div>Hello, World!</div>\n\t</body>\n</html>\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/18-render-once.md",
    "content": "# Render once\n\nIf you need to render something to the page once per page, you can create a `*OnceHandler` with `templ.NewOnceHandler()` and use its `Once()` method.\n\nThe `*OnceHandler.Once()` method ensures that the content is only rendered once per distinct context passed to the component's `Render` method, even if the component is rendered multiple times.\n\n## Example\n\nThe `hello` JavaScript function is only rendered once, even though the `hello` component is rendered twice.\n\n:::warning\nDont write `@templ.NewOnceHandle().Once()` - this creates a new `*OnceHandler` each time the `Once` method is called, and will result in the content being rendered multiple times.\n:::\n\n```templ title=\"component.templ\"\npackage once\n\nvar helloHandle = templ.NewOnceHandle()\n\ntempl hello(label, name string) {\n  @helloHandle.Once() {\n    <script>\n      function hello(name) {\n        alert('Hello, ' + name + '!');\n      }\n    </script>\n  }\n  <input type=\"button\" value={ label } data-name={ name } onclick=\"hello(this.getAttribute('data-name'))\"/>\n}\n\ntempl page() {\n  @hello(\"Hello User\", \"user\")\n  @hello(\"Hello World\", \"world\")\n}\n```\n\n```html title=\"Output\"\n<script>\n  function hello(name) {\n    alert('Hello, ' + name + '!');\n  }\n</script>\n<input type=\"button\" value=\"Hello User\" data-name=\"user\" onclick=\"hello(this.getAttribute('data-name'))\">\n<input type=\"button\" value=\"Hello World\" data-name=\"world\" onclick=\"hello(this.getAttribute('data-name'))\">\n```\n\n:::tip\nNote the use of the `data-name` attribute to pass the `name` value from server-side Go code to the client-side JavaScript code.\n\nThe value of `name` is collected by the `onclick` handler, and passed to the `hello` function.\n\nTo pass complex data structures, consider using a `data-` attribute to pass a JSON string using the `templ.JSONString` function, or use the `templ.JSONScript` function to create a templ component that creates a `<script>` element containing JSON data.\n:::\n\n## Common use cases\n\n- Rendering a `<style>` tag that contains CSS classes required by a component.\n- Rendering a `<script>` tag that contains JavaScript required by a component.\n- Rendering a `<link>` tag that contains a reference to a stylesheet.\n\n## Usage across packages\n\nExport a component that contains the `*OnceHandler` and the content to be rendered once.\n\nFor example, create a `deps` package that contains a `JQuery` component that renders a `<script>` tag that references the jQuery library.\n\n```templ title=\"deps/deps.templ\"\npackage deps\n\nvar jqueryHandle = templ.NewOnceHandle()\n\ntempl JQuery() {\n  @jqueryHandle.Once() {\n    <script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>\n  }\n}\n```\n\nYou can then use the `JQuery` component in other packages, and the jQuery library will only be included once in the rendered HTML.\n\n```templ title=\"main.templ\"\npackage main\n\nimport \"deps\"\n\ntempl page() {\n  <html>\n    <head>\n      @deps.JQuery()\n    </head>\n    <body>\n      <h1>Hello, World!</h1>\n      @button()\n    </body>\n  </html>\n}\n\ntempl button() {\n  @deps.JQuery()\n  <button>Click me</button>\n}\n```\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/19-fragments.md",
    "content": "# Fragments\n\nThe `templ.Fragment` component can be used to render a subsection of a template, discarding all other output.\n\nFragments work well as an optimisation for htmx, as discussed in https://htmx.org/essays/template-fragments/\n\n## Define fragments\n\nDefine a fragment with `@templ.Fragment(\"name\")`, where `\"name\"` is the identifier for the fragment.\n\n```templ\ntempl Page() {\n  <div>Page Header</div>\n  @templ.Fragment(\"name\") {\n    <div>Content of the fragment</div>\n  }\n}\n```\n\nTo avoid name clashes with other libraries, you can define a custom type for your package.\n\n```templ\ntype nameFragmentKey struct {}\nvar Name = nameFragmentKey{}\n\ntempl Page() {\n  <div>Page Header</div>\n  @templ.Fragment(Name) {\n    <div>Content of the fragment</div>\n  }\n}\n```\n\n## Use with HTTP\n\nThe most common use case for `Fragment` is to render only a specific part of the template to the HTML response, while discarding the rest of the output.\n\nTo render only the \"name\" fragment from the `Page` template, use the `templ.WithFragments(\"name\")` option when creating the HTTP handler:\n\n```go title=\"main.go\"\nhandler := templ.Handler(Page(), templ.WithFragments(\"name\"))\nhttp.Handle(\"/\", handler)\n```\n\nWhen the HTTP request is made, only the content of the specified fragment will be returned in the response:\n\n```html title=\"output.html\"\n<div>Content of the fragment</div>\n```\n\n:::note\nThe whole of the template is rendered, so any function calls or logic in the template will still be executed, but only the specified fragment's output is sent to the client.\n:::\n\nIf the `templ.WithFragments(\"name\")` option is omitted, the whole page is rendered as normal.\n\n```go title=\"main.go\"\nhandler := templ.Handler(Page())\nhttp.Handle(\"/\", handler)\n```\n\n```html title=\"output.html\"\n<div>Page Header</div>\n<div>Content of the fragment</div>\n```\n\n## Use outside of an HTTP handler\n\nTo use outside of an HTTP handler, e.g. when generating static content, you can render fragments with the `templ.RenderFragments` function.\n\n```go\nw := new(bytes.Buffer)\nif err := templ.RenderFragments(context.Background(), w, fragmentPage, \"name\"); err != nil {\n  t.Fatalf(\"failed to render: %v\", err)\n}\n\n// <div>Content of the fragment</div>\nhtml := w.String()\n```\n\n:::note\nAll fragments with matching identifiers will be rendered. If the fragment identifier isn't matched, no output will be produced.\n:::\n\n## Nested fragments\n\nFragments can be nested, allowing for complex structures to be defined and rendered selectively.\n\nGiven this example templ file:\n\n```templ\ntempl Page() {\n\t@templ.Fragment(\"outer\") {\n\t\t<div>Outer Fragment Start</div>\n\t\t@templ.Fragment(\"inner\") {\n\t\t\t<div>Inner Fragment Content</div>\n\t\t}\n\t\t<div>Outer Fragment End</div>\n\t}\n}\n```\n\nIf the `outer` fragment is selected for rendering, then the `inner` fragment is also rendered.\n\n## htmx example\n\n```templ title=\"main.templ\"\npackage main\n\nimport (\n  \"fmt\"\n  \"net/http\"\n  \"strconv\"\n)\n\ntype PageState struct {\n  Counter int\n  Next    int\n}\n\ntempl Page(state PageState) {\n  <html>\n    <head>\n       <script src=\"https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js\"></script>\n       <link rel=\"stylesheet\" href=\"https://unpkg.com/missing.css@1.1.3/dist/missing.min.css\"/>\n    </head>\n    <body>\n      @templ.Fragment(\"buttonOnly\") {\n        <button hx-get={ fmt.Sprintf(\"/?counter=%d&template=buttonOnly\", state.Next) } hx-swap=\"outerHTML\">\n          This Button Has Been Clicked { state.Counter } Times\n        </button>\n      }\n    </body>\n  </html>\n}\n\n// handleRequest does the work to execute the template (or fragment) and serve the result.\n// It's mostly boilerplate, so don't get hung up on it.\nfunc handleRequest(w http.ResponseWriter, r *http.Request) {\n  // Collect state info to pass to the template.\n  var state PageState\n  state.Counter, _ = strconv.Atoi(r.URL.Query().Get(\"counter\"))\n  state.Next = state.Counter + 1\n\n  // If the template querystring paramater is set, render the pecific fragment.\n  var opts []func(*templ.ComponentHandler)\n  if templateName := r.URL.Query().Get(\"template\"); templateName != \"\" {\n    opts = append(opts, templ.WithFragments(templateName))\n  }\n\n  // Render the template or fragment and serve it.\n  templ.Handler(Page(state), opts...).ServeHTTP(w, r)\n}\n\nfunc main() {\n  // Handle the template.\n  http.HandleFunc(\"/\", handleRequest)\n  \n  // Start the server.\n  fmt.Println(\"Server is running at http://localhost:8080\")\n  http.ListenAndServe(\"localhost:8080\", nil)\n}\n```\n\n:::note\nThis was adapted from `benpate`'s Go stdlib example at https://gist.github.com/benpate/f92b77ea9b3a8503541eb4b9eb515d8a\n:::\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/20-using-react-with-templ.md",
    "content": "# Using React with templ\n\ntempl is great for server-side rendering. Combined with [htmx](https://htmx.org/), it's even more powerful, since htmx can be used to replace elements within the page with updated HTML fetched from the server, providing many of the benefits of React with reduced overall complexity. See [/server-side-rendering/htmx](/server-side-rendering/htmx) for an example.\n\nHowever, React has a huge ecosystem of rich interactive components, so being able to tap into the ecosystem is very useful.\n\nWith templ, it's more likely that you will use React components as [islands of interactivity](https://www.patterns.dev/vanilla/islands-architecture/) rather than taking over all aspects of displaying your app, with templ taking over server-side rendering, but using React to provide specific features on the client side.\n\n## Using React components\n\nFirst, lets start by rendering simple React components.\n\n### Create React components\n\nTo use React components in your templ app, create your React components using TSX (TypeScript) or JSX as usual.\n\n```tsx title=\"react/components.tsx\"\nexport const Header = () => (<h1>React component Header</h1>);\n\nexport const Body = () => (<div>This is client-side content from React</div>);\n```\n\n### Create a templ page\n\nNext, use templ to create a page containing HTML elements with specific IDs.\n\n:::note\nThis page defines elements with ids of `react-header` and `react-content`.\n\nA `<script>` element loads in a JavaScript bundle that we haven't created yet.\n:::\n\n```templ title=\"components.templ\"\npackage main\n\ntempl page() {\n\t<html>\n\t\t<body>\n\t\t\t<div id=\"react-header\"></div>\n\t\t\t<div id=\"react-content\"></div>\n\t\t\t<div>This is server-side content from templ.</div>\n\t\t\t<!-- Load the React bundle created using esbuild -->\n\t\t\t<script src=\"static/index.js\"></script>\n\t\t</body>\n\t</html>\n}\n```\n\n:::tip\nRemember to run `templ generate` when you've finished writing your templ file.\n:::\n\n### Render React components into the IDs\n\nWrite TypeScript or JavaScript to render the React components into the HTML elements that are rendered by templ.\n\n```typescript title=\"react/index.ts\"\nimport { createRoot } from 'react-dom/client';\nimport { Header, Body } from './components';\n\n// Render the React component into the templ page at the react-header.\nconst headerRoot = document.getElementById('react-header');\nif (!headerRoot) {\n\tthrow new Error('Could not find element with id react-header');\n}\nconst headerReactRoot = createRoot(headerRoot);\nheaderReactRoot.render(Header());\n\n// Add the body React component.\nconst contentRoot = document.getElementById('react-content');\nif (!contentRoot) {\n\tthrow new Error('Could not find element with id react-content');\n}\nconst contentReactRoot = createRoot(contentRoot);\ncontentReactRoot.render(Body());\n```\n\n### Create a client-side bundle\n\nTo turn the JSX, TSX, TypeScript and JavaScript code into a bundle that can run in the browser, use a bundling tool.\n\nhttps://esbuild.github.io/ is commonly used for this task. It's fast, it's easy to use, and it's written in Go.\n\nExecuting `esbuild` with the following arguments creates an `index.js` file in the static directory.\n\n```bash\nesbuild --bundle index.ts --outdir=../static --minify\n```\n\n### Serve the templ component and client side bundle\n\nTo serve the server-side rendered templ template, and the client-side JavaScript bundle created in the previous step, setup a Go web server.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\tmux := http.NewServeMux()\n\n\t// Serve the templ page.\n\tmux.Handle(\"/\", templ.Handler(page()))\n\n\t// Serve static content.\n\tmux.Handle(\"/static/\", http.StripPrefix(\"/static/\", http.FileServer(http.Dir(\"static\"))))\n\n\t// Start the server.\n\tfmt.Println(\"listening on localhost:8080\")\n\tif err := http.ListenAndServe(\"localhost:8080\", mux); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\n### Results\n\nPutting this together results in a web page that renders server-side HTML using templ. The server-side HTML includes a link to the static React bundle.\n\n```mermaid\nsequenceDiagram\n    browser->>app: GET /\n    activate app\n\tapp->>templ_component: Render\n\tactivate templ_component\n\ttempl_component->>app: HTML\n\tdeactivate templ_component\n    app->>browser: HTML\n    deactivate app\n\tbrowser->>app: GET /static/index.js\n\tactivate app\n\tapp->>browser: JS bundle containing React components\n\tdeactivate app\n\tbrowser->>browser: render components into react-header and react-content\n```\n\n## Passing server-side data to React components\n\nMoving on from the previous example, it's possible to pass data to client-side React components.\n\n### Add a React component that accepts data arguments\n\nFirst, add a new component.\n\n```tsx title=\"react/components.tsx\"\nexport const Hello = (name: string) => (\n  <div>Hello {name} (Client-side React, rendering server-side data)</div>\n);\n```\n\n### Export a JavaScript function that renders the React component to a HTML element\n\n```typescript title=\"react/index.ts\"\n// Update the import to add the new Hello React component.\nimport { Header, Body, Hello } from './components';\n\n// Previous script contents...\n  \nexport function renderHello(e: HTMLElement) {\n  const name = e.getAttribute('data-name') ?? \"\";\n  createRoot(e).render(Hello(name));\n}\n```\n\n### Update the templ component to use the new function\n\nNow that we have a `renderHello` function that will render the React component to the given element, we can update the templ components to use it.\n\nIn templ, we can add a `Hello` component that does two things:\n\n1. Renders an element for the React component to be loaded into that sets the `data-name` attribute to the value of the server-side `name` field.\n2. Writes out JS that calls the `renderHello` function to mount the React component into the element.\n\n:::note\nThe template renders three copies of the `Hello` React component, passing in a distinct `name` parameter (\"Alice\", \"Bob\" and \"Charlie\").\n:::\n\n```templ title=\"components.templ\"\npackage main\n\nimport \"fmt\"\n\ntempl Hello(name string) {\n\t<div data-name={ name }>\n\t\t<script>\n\t\t\tbundle.renderHello(document.currentScript.closest('div'));\n\t\t</script>\n\t</div>\n}\n\ntempl page() {\n\t<html>\n\t\t<head>\n\t\t\t<title>React integration</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<div id=\"react-header\"></div>\n\t\t\t<div id=\"react-content\"></div>\n\t\t\t<div>\n\t\t\t\tThis is server-side content from templ.\n\t\t\t</div>\n\t\t\t<!-- Load the React bundle that was created using esbuild -->\n\t\t\t<!-- Since the bundle was coded to expect the react-header and react-content elements to exist already, in this case, the script has to be loaded after the elements are on the page -->\n\t\t\t<script src=\"static/index.js\"></script>\n\t\t\t<!-- Now that the React bundle is loaded, we can use the functions that are in it -->\n\t\t\t<!-- the renderName function in the bundle can be used, but we want to pass it some server-side data -->\n\t\t\tfor _, name := range []string{\"Alice\", \"Bob\", \"Charlie\"} {\n\t\t\t\t@Hello(name)\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n```\n\n### Update the `esbuild` command\n\nThe `bundle` namespace in JavaScript is created by adding a `--global-name` argument to `esbuild`. The argument causes any exported functions in `index.ts` to be added to that namespace.\n\n```bash\nesbuild --bundle index.ts --outdir=../static --minify --global-name=bundle\n```\n\n### Results\n\nThe HTML that's rendered is:\n\n```html\n<html>\n  <head>\n    <title>React integration</title>\n  </head>\n  <body>\n    <div id=\"react-header\"></div>\n    <div id=\"react-content\"></div>\n    <div>This is server-side content from templ.</div>\n\n    <script src=\"static/index.js\"></script>\n\n    <div data-name=\"Alice\">\n      <script>\n        // Place the React component into the parent div.\n        bundle.renderHello(document.currentScript.closest('div'));\n      </script>\n    </div>\n    <div data-name=\"Bob\">\n      <script>\n        // Place the React component into the parent div.\n\tbundle.renderHello(document.currentScript.closest('div'));\n      </script>\n    </div>\n    <div data-name=\"Charlie\">\n      <script>\n        // Place the React component into the parent div.\n\tbundle.renderHello(document.currentScript.closest('div'));\n      </script>\n    </div>\n  </body>\n</html>\n```\n\nAnd the browser shows the expected content after rendering the client side React components.\n\n```\nReact component Header\nThis is client-side content from React\nThis is server-side content from templ.\nHello Alice (Client-side React, rendering server-side data)\nHello Bob (Client-side React, rendering server-side data)\nHello Charlie (Client-side React, rendering server-side data)\n```\n\n## Example code\n\nSee https://github.com/a-h/templ/tree/main/examples/integration-react for a complete example.\n"
  },
  {
    "path": "docs/docs/03-syntax-and-usage/_category_.json",
    "content": "{\n  \"position\": 3,\n  \"label\": \"Syntax and usage\"\n}\n"
  },
  {
    "path": "docs/docs/04-core-concepts/01-components.md",
    "content": "# Components\n\ntempl Components are markup and code that is compiled into functions that return a `templ.Component` interface by running the `templ generate` command.\n\nComponents can contain templ elements that render HTML, text, expressions that output text or include other templates, and branching statements such as `if` and `switch`, and `for` loops.\n\n```templ title=\"header.templ\"\npackage main\n\ntempl headerTemplate(name string) {\n  <header data-testid=\"headerTemplate\">\n    <h1>{ name }</h1>\n  </header>\n}\n```\n\nThe generated code is a Go function that returns a `templ.Component`.\n\n```go title=\"header_templ.go\"\nfunc headerTemplate(name string) templ.Component {\n  // Generated contents\n}\n```\n\n`templ.Component` is an interface that has a `Render` method on it that is used to render the component to an `io.Writer`.\n\n```go\ntype Component interface {\n\tRender(ctx context.Context, w io.Writer) error\n}\n```\n\n:::tip\nSince templ produces Go code, you can share templates the same way that you share Go code - by sharing your Go module.\n\ntempl follows the same rules as Go. If a `templ` block starts with an uppercase letter, then it is public, otherwise, it is private.\n\nA `templ.Component` may write partial output to the `io.Writer` if it returns an error. If you want to ensure you only get complete output or nothing, write to a buffer first and then write the buffer to an `io.Writer`.\n:::\n\n## Code-only components\n\nSince templ Components ultimately implement the `templ.Component` interface, any code that implements the interface can be used in place of a templ component generated from a `*.templ` file.\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc button(text string) templ.Component {\n\treturn templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t_, err := io.WriteString(w, \"<button>\"+text+\"</button>\")\n\t\treturn err\n\t})\n}\n\nfunc main() {\n\tbutton(\"Click me\").Render(context.Background(), os.Stdout)\n}\n```\n\n```html title=\"Output\"\n<button>\n Click me\n</button>\n```\n\n:::warning\nThis code is unsafe! In code-only components, you're responsible for escaping the HTML content yourself, e.g. with the `templ.EscapeString` function.\n:::\n\n## Method components\n\ntempl components can be returned from methods (functions attached to types).\n\nGo code:\n\n```templ\npackage main\n\nimport \"os\"\n\ntype Data struct {\n\tmessage string\n}\n\ntempl (d Data) Method() {\n\t<div>{ d.message }</div>\n}\n\nfunc main() {\n\td := Data{\n\t\tmessage: \"You can implement methods on a type.\",\n\t}\n\td.Method().Render(context.Background(), os.Stdout)\n}\n```\n\nIt is also possible to initialize a struct and call its component method inline.\n\n```templ\npackage main\n\nimport \"os\"\n\ntype Data struct {\n\tmessage string\n}\n\ntempl (d Data) Method() {\n\t<div>{ d.message }</div>\n}\n\ntempl Message() {\n    <div>\n        @Data{\n            message: \"You can implement methods on a type.\",\n        }.Method()\n    </div>\n}\n\nfunc main() {\n\tMessage().Render(context.Background(), os.Stdout)\n}\n```\n\n"
  },
  {
    "path": "docs/docs/04-core-concepts/02-template-generation.md",
    "content": "# Template generation\n\nTo generate Go code from `*.templ` files, use the `templ` command line tool.\n\n```\ntempl generate\n```\n\nThe `templ generate` recurses into subdirectories and generates Go code for each `*.templ` file it finds.\n\nThe command outputs warnings, and a summary of updates.\n\n```\n(!) void element <input> should not have child content [ from=12:2 to=12:7 ]\n(✓) Complete [ updates=62 duration=144.677334ms ]\n```\n\n## Advanced options\n\nThe `templ generate` command has a `--help` option that prints advanced options.\n\nThese include the ability to generate code for a single file and to choose the number of parallel workers that `templ generate` uses to create Go files.\n\nBy default `templ generate` uses the number of CPUs that your machine has installed.\n\n```\ntempl generate --help\n```\n\n```\nusage: templ generate [<args>...]\n\nGenerates Go code from templ files.\n\nArgs:\n  -path <path>\n    Generates code for all files in path. (default .)\n  -f <file>\n    Optionally generates code for a single file, e.g. -f header.templ\n  -stdout\n    Prints to stdout instead of writing generated files to the filesystem.\n    Only applicable when -f is used.\n  -source-map-visualisations\n    Set to true to generate HTML files to visualise the templ code and its corresponding Go code.\n  -include-version\n    Set to false to skip inclusion of the templ version in the generated code. (default true)\n  -include-timestamp\n    Set to true to include the current time in the generated code.\n  -watch\n    Set to true to watch the path for changes and regenerate code.\n  -cmd <cmd>\n    Set the command to run after generating code.\n  -proxy\n    Set the URL to proxy after generating code and executing the command.\n  -proxyport\n    The port the proxy will listen on. (default 7331)\n  -proxybind\n    The address the proxy will listen on. (default 127.0.0.1)\n  -notify-proxy\n    If present, the command will issue a reload event to the proxy 127.0.0.1:7331, or use proxyport and proxybind to specify a different address.\n  -w\n    Number of workers to use when generating code. (default runtime.NumCPUs)\n  -lazy\n    Only generate .go files if the source .templ file is newer.\t\n  -pprof\n    Port to run the pprof server on.\n  -keep-orphaned-files\n    Keeps orphaned generated templ files. (default false)\n  -v\n    Set log verbosity level to \"debug\". (default \"info\")\n  -log-level\n    Set log verbosity level. (default \"info\", options: \"debug\", \"info\", \"warn\", \"error\")\n  -help\n    Print help and exit.\n\nExamples:\n\n  Generate code for all files in the current directory and subdirectories:\n\n    templ generate\n\n  Generate code for a single file:\n\n    templ generate -f header.templ\n\n  Watch the current directory and subdirectories for changes and regenerate code:\n\n    templ generate -watch\n```\n\n:::tip\nThe `templ generate --watch` option watches files for changes and runs templ generate when required.\n\nHowever, the code generated in this mode is not optimised for production use.\n:::\n"
  },
  {
    "path": "docs/docs/04-core-concepts/03-testing.md",
    "content": "# Testing\n\nTo test that data is rendered as expected, there are two main ways to do it:\n\n* Expectation testing - testing that specific expectations are met by the output.\n* Snapshot testing - testing that outputs match a pre-written output.\n\n## Expectation testing\n\nExpectation testing validates that the right data appears in the output in the right format and position.\n\nThe example at https://github.com/a-h/templ/blob/main/examples/blog/posts_test.go shows how to test that a list of posts is rendered correctly.\n\nThese tests use the `goquery` library to parse HTML and check that expected elements are present. `goquery` is a jQuery-like library for Go, that is useful for parsing and querying HTML. You’ll need to run `go get github.com/PuerkitoBio/goquery` to add it to your `go.mod` file.\n\n### Testing components\n\nThe test sets up a pipe to write templ's HTML output to, and reads the output from the pipe, parsing it with `goquery`.\n\nFirst, we test the page header. To use `goquery` to inspect the output, we’ll need to connect the header component’s `Render` method to the `goquery.NewDocumentFromReader` function with an `io.Pipe`.\n\n```go\nfunc TestHeader(t *testing.T) {\n    // Pipe the rendered template into goquery.\n    r, w := io.Pipe()\n    go func () {\n        _ = headerTemplate(\"Posts\").Render(context.Background(), w)\n        _ = w.Close()\n    }()\n    doc, err := goquery.NewDocumentFromReader(r)\n    if err != nil {\n        t.Fatalf(\"failed to read template: %v\", err)\n    }\n    // Expect the component to be present.\n    if doc.Find(`[data-testid=\"headerTemplate\"]`).Length() == 0 {\n        t.Error(\"expected data-testid attribute to be rendered, but it wasn't\")\n    }\n    // Expect the page name to be set correctly.\n    expectedPageName := \"Posts\"\n    if actualPageName := doc.Find(\"h1\").Text(); actualPageName != expectedPageName {\n        t.Errorf(\"expected page name %q, got %q\", expectedPageName, actualPageName)\n    }\n}\n```\n\nThe header template (the \"subject under test\") includes a placeholder for the page name, and a `data-testid` attribute that makes it easier to locate the `headerTemplate` within the HTML using a CSS selector of `[data-testid=\"headerTemplate\"]`.\n\n```go\ntempl headerTemplate(name string) {\n    <header data-testid=\"headerTemplate\">\n        <h1>{ name }</h1>\n    </header>\n}\n```\n\nWe can also test that the navigation bar was rendered.\n\n```go\nfunc TestNav(t *testing.T) {\n    r, w := io.Pipe()\n    go func() {\n        _ = navTemplate().Render(context.Background(), w)\n        _ = w.Close()\n    }()\n    doc, err := goquery.NewDocumentFromReader(r)\n    if err != nil {\n        t.Fatalf(\"failed to read template: %v\", err)\n    }\n    // Expect the component to include a testid.\n    if doc.Find(`[data-testid=\"navTemplate\"]`).Length() == 0 {\n        t.Error(\"expected data-testid attribute to be rendered, but it wasn't\")\n    }\n}\n```\n\nTesting that it was rendered is useful, but it's even better to test that the navigation includes the correct `nav` items.\n\nIn this test, we find all of the `a` elements within the `nav` element, and check that they match the expected items.\n\n```go\nnavItems := []string{\"Home\", \"Posts\"}\n\ndoc.Find(\"nav a\").Each(func(i int, s *goquery.Selection) {\n    expected := navItems[i]\n    if actual := s.Text(); actual != expected {\n        t.Errorf(\"expected nav item %q, got %q\", expected, actual)\n    }\n})\n```\n\nTo test the posts, we can use the same approach. We test that the posts are rendered correctly, and that the expected data is present.\n\n### Testing whole pages\n\nNext, we may want to go a level higher and test the entire page. \n\nPages are also templ components, so the tests are structured in the same way.\n\nThere’s no need to test for the specifics about what gets rendered in the `navTemplate` or `homeTemplate` at the page level, because they’re already covered in other tests.\n\nSome developers prefer to only test the external facing part of their code (e.g. at a page level), rather than testing each individual component, on the basis that it’s slower to make changes if the implementation is too tightly controlled.\n\nFor example, if a component is reused across pages, then it makes sense to test that in detail in its own test. In the pages or higher-order components that use it, there’s no point testing it again at that level, so we only check that it was rendered to the output by looking for its data-testid attribute, unless we also need to check what we're passing to it.\n\n### Testing the HTTP handler\n\nFinally, we want to test the posts HTTP handler. This requires a different approach.\n\nWe can use the `httptest` package to create a test server, and use the `net/http` package to make a request to the server and check the response.\n\nThe tests configure the `GetPosts` function on the `PostsHandler` with a mock that returns a \"database error\", while the other returns a list of two posts. Here's what the `PostsHandler` looks like:\n\n```go\ntype PostsHandler struct {\n    Log      *log.Logger\n    GetPosts func() ([]Post, error)\n}\n```\n\nIn the error case, the test asserts that the error message was displayed, while in the success case, it checks that the `postsTemplate` is present. It does not check that the posts have actually been rendered properly or that specific fields are visible, because that’s already tested at the component level.\n\nTesting it again here would make the code resistant to refactoring and rework, but then again, we might have missed actually passing the posts we got back from the database to the posts template, so it’s a matter of risk appetite vs refactor resistance.\n\nNote the switch to the table-driven testing format, a popular approach in Go for testing multiple scenarios with the same test code.\n```go\nfunc TestPostsHandler(t *testing.T) {\n    tests := []struct {\n        name           string\n        postGetter     func() (posts []Post, err error)\n        expectedStatus int\n        assert         func(doc *goquery.Document)\n    }{\n        {\n            name: \"database errors result in a 500 error\",\n            postGetter: func() (posts []Post, err error) {\n                return nil, errors.New(\"database error\")\n            },\n            expectedStatus: http.StatusInternalServerError,\n            assert: func(doc *goquery.Document) {\n                expected := \"failed to retrieve posts\\n\"\n                if actual := doc.Text(); actual != expected {\n                    t.Errorf(\"expected error message %q, got %q\", expected, actual)\n                }\n            },\n        },\n        {\n            name: \"database success renders the posts\",\n            postGetter: func() (posts []Post, err error) {\n                return []Post{\n                    {Name: \"Name1\", Author: \"Author1\"},\n                    {Name: \"Name2\", Author: \"Author2\"},\n                }, nil\n            },\n            expectedStatus: http.StatusInternalServerError,\n            assert: func(doc *goquery.Document) {\n                if doc.Find(`[data-testid=\"postsTemplate\"]`).Length() == 0 {\n                    t.Error(\"expected posts to be rendered, but it wasn't\")\n                }\n            },\n        },\n    }\n    for _, test := range tests {\n        // Arrange.\n        w := httptest.NewRecorder()\n        r := httptest.NewRequest(http.MethodGet, \"/posts\", nil)\n\n        ph := NewPostsHandler()\n        ph.Log = log.New(io.Discard, \"\", 0) // Suppress logging.\n        ph.GetPosts = test.postGetter\n\n        // Act.\n        ph.ServeHTTP(w, r)\n        doc, err := goquery.NewDocumentFromReader(w.Result().Body)\n        if err != nil {\n            t.Fatalf(\"failed to read template: %v\", err)\n        }\n\n        // Assert.\n        test.assert(doc)\n    }\n}\n```\n\n### Summary\n\n- goquery can be used effectively with templ for writing component level tests.\n- Adding `data-testid` attributes to your code simplifies the test expressions you need to write to find elements within the output and makes your tests less brittle.\n- Testing can be split between the two concerns of template rendering, and HTTP handlers.\n\n## Snapshot testing\n\nSnapshot testing is a more broad check. It simply checks that the output hasn't changed since the last time you took a copy of the output.\n\nIt relies on manually checking the output to make sure it's correct, and then \"locking it in\" by using the snapshot.\n\ntempl uses this strategy to check for regressions in behaviour between releases, as per https://github.com/a-h/templ/blob/main/generator/test-html-comment/render_test.go\n\nTo make it easier to compare the output against the expected HTML, templ uses a HTML formatting library before executing the diff.\n\nThe `htmldiff.Diff` function requires `prettier` to be installed and available in the shell's PATH. See https://prettier.io/docs/en/install for installation instructions.\n\n```go\npackage testcomment\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(\"sample content\")\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n```\n"
  },
  {
    "path": "docs/docs/04-core-concepts/04-view-models.md",
    "content": "# View models\n\nWith templ, you can pass any Go type into your template as parameters, and you can call arbitrary functions.\n\nHowever, if the parameters of your template don't closely map to what you're displaying to users, you may find yourself calling a lot of functions within your templ files to reshape or adjust data, or to carry out complex repeated string interpolation or URL constructions.\n\nThis can make template rendering hard to test, because you need to set up complex data structures in the right way in order to render the HTML. If the template calls APIs or accesses databases from within the templates, it's even harder to test, because then testing your templates becomes an integration test.\n\nA more reliable approach can be to create a \"View model\" that only contains the fields that you intend to display, and where the data structure closely matches the structure of the visual layout.\n\n```go\npackage invitesget\n\ntype Handler struct {\n  Invites *InviteService\n}\n\nfunc (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n  invites, err := h.Invites.Get(getUserIDFromContext(r.Context()))\n  if err != nil {\n     //TODO: Log error server side.\n  }\n  m := NewInviteComponentViewModel(invites, err)\n  teamInviteComponent(m).Render(r.Context(), w)\n}\n\nfunc NewInviteComponentViewModel(invites []models.Invite, err error) (m InviteComponentViewModel) {\n  m.InviteCount = len(invites)\n  if err != nil {\n    m.ErrorMessage = \"Failed to load invites, please try again\"\n  }\n  return m\n}\n\n\ntype InviteComponentViewModel struct {\n  InviteCount int\n  ErrorMessage string\n}\n\ntempl teamInviteComponent(model InviteComponentViewModel) {\n\tif model.InviteCount > 0 {\n\t\t<div>You have { fmt.Sprintf(\"%d\", model.InviteCount) } pending invites</div>\n\t}\n        if model.ErrorMessage != \"\" {\n\t\t<div class=\"error\">{ model.ErrorMessage }</div>\n        }\n}\n```\n"
  },
  {
    "path": "docs/docs/04-core-concepts/_category_.json",
    "content": "{\n  \"position\": 4,\n  \"label\": \"Core concepts\"\n}\n"
  },
  {
    "path": "docs/docs/05-server-side-rendering/01-creating-an-http-server-with-templ.md",
    "content": "# Creating an HTTP server with templ\n\n### Static pages\n\nTo use a templ component as a HTTP handler, the `templ.Handler` function can be used.\n\nThis is suitable for use when the component is not used to display dynamic data.\n\n```go title=\"components.templ\"\npackage main\n\ntempl hello() {\n\t<div>Hello</div>\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\thttp.Handle(\"/\", templ.Handler(hello()))\n\n\thttp.ListenAndServe(\":8080\", nil)\n}\n```\n\n### Displaying fixed data\n\nIn the previous example, the `hello` component does not take any parameters. Let's display the time when the server was started instead.\n\n```templ title=\"components.templ\"\npackage main\n\nimport \"time\"\n\ntempl timeComponent(d time.Time) {\n\t<div>{ d.String() }</div>\n}\n\ntempl notFoundComponent() {\n\t<div>404 - Not found</div>\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\thttp.Handle(\"/\", templ.Handler(timeComponent(time.Now())))\n\thttp.Handle(\"/404\", templ.Handler(notFoundComponent(), templ.WithStatus(http.StatusNotFound)))\n\n\thttp.ListenAndServe(\":8080\", nil)\n}\n```\n\n:::tip\nThe `templ.WithStatus`, `templ.WithContentType`, and `templ.WithErrorHandler` functions can be passed as parameters to the `templ.Handler` function to control how content is rendered.\n:::\n\nThe output will always be the date and time that the web server was started up, not the current time.\n\n```\n2023-04-26 08:40:03.421358 +0100 BST m=+0.000779501\n```\n\nTo display the current time, we could update the component to use the `time.Now()` function itself, but this would limit the reusability of the component. It's better when components take parameters for their display values.\n\n:::tip\nGood templ components are idempotent, pure functions - they don't rely on data that is not passed in through parameters. As long as the parameters are the same, they always return the same HTML - they don't rely on any network calls or disk access.\n:::\n\n## Displaying dynamic data\n\nLet's update the previous example to display dynamic content.\n\ntempl components implement the `templ.Component` interface, which provides a `Render` method.\n\nThe `Render` method can be used within HTTP handlers to write HTML to the `http.ResponseWriter`.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"net/http\"\n)\n\nfunc main() {\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\thello().Render(r.Context(), w)\n\t})\n\n\thttp.ListenAndServe(\":8080\", nil)\n}\n```\n\nBuilding on that example, we can implement the Go HTTP handler interface and use the component within our HTTP handler. In this case, displaying the latest date and time, instead of the date and time when the server started up.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc NewNowHandler(now func() time.Time) NowHandler {\n\treturn NowHandler{Now: now}\n}\n\ntype NowHandler struct {\n\tNow func() time.Time\n}\n\nfunc (nh NowHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\ttimeComponent(nh.Now()).Render(r.Context(), w)\n}\n\nfunc main() {\n\thttp.Handle(\"/\", NewNowHandler(time.Now))\n\n\thttp.ListenAndServe(\":8080\", nil)\n}\n```\n"
  },
  {
    "path": "docs/docs/05-server-side-rendering/02-example-counter-application.md",
    "content": "# Example: Counter application\n\nWeb applications typically need to store application state, some of which is per-user, and some of which is global.\n\nApplications also need to handle input from users, update the state, and display updated HTML.\n\n```mermaid\nflowchart TD\n  b[Browser] --HTTP POST request--> ws[Web Server];\n  ws --Update state--> ws;\n  ws --HTTP POST response--> b;\n```\n\n## Updating global state\n\nFirst, define a HTML form post with two buttons. One to update a global state, and one for a per-user state.\n\n```templ title=\"components.templ\"\npackage main\n\nimport \"strconv\"\n\ntempl counts(global, user int) {\n\t<div>Global: { strconv.Itoa(global) }</div>\n\t<div>User: { strconv.Itoa(user) }</div>\n}\n\ntempl form() {\n\t<form action=\"/\" method=\"POST\">\n\t\t<div><button type=\"submit\" name=\"global\" value=\"global\">Global</button></div>\n\t\t<div><button type=\"submit\" name=\"user\" value=\"user\">User</button></div>\n\t</form>\n}\n\ntempl page(global, user int) {\n\t@counts(global, user)\n\t@form()\n}\n```\n\n:::tip\nWhile we could read the global state directly, we're following the best practice that templ components are idempotent, pure functions.\n:::\n\nThe HTTP form in the templates posts data back to the `/` handler.\n\nThe `/` handler looks at the HTTP request. If it's a GET request, the templ templates are rendered by the `getHandler`.\n\nIf it's a POST request, then the `postHandler` is used. This parses the data sent over HTTP, and looks to see if the `global` button was the button that submitted the form, and increments the global count value if it was.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype GlobalState struct {\n\tCount int\n}\n\nvar global GlobalState\n\nfunc getHandler(w http.ResponseWriter, r *http.Request) {\n\tcomponent := page(global.Count, 0)\n\tcomponent.Render(r.Context(), w)\n}\n\nfunc postHandler(w http.ResponseWriter, r *http.Request) {\n\t// Update state.\n\tr.ParseForm()\n\n\t// Check to see if the global button was pressed.\n\tif r.Form.Has(\"global\") {\n\t\tglobal.Count++\n\t}\n\t//TODO: Update session.\n\n\t// Display the form.\n\tgetHandler(w, r)\n}\n\nfunc main() {\n\t// Handle POST and GET requests.\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.Method == http.MethodPost {\n\t\t\tpostHandler(w, r)\n\t\t\treturn\n\t\t}\n\t\tgetHandler(w, r)\n\t})\n\n\t// Start the server.\n\tfmt.Println(\"listening on http://localhost:8000\")\n\tif err := http.ListenAndServe(\"localhost:8000\", nil); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\n:::note\nIn this example, the global state is stored in RAM, and will be lost when the web server reboots. To support load-balanced web servers, and stateless function deployments, you might consider storing the state in a data store such as Redis, DynamoDB, or Cloud Firestore.\n:::\n\n## Adding per-user session state\n\nIn a HTTP application, per-user state information is partitioned by a HTTP cookie. Setting a cookie with a unique random value for each user (typically a V4 UUID or similar) allows the HTTP handlers to identify each user by reading the cookie value presented by the user's browser.\n\nCookies that identify a user while they're using a site are known as \"session cookies\". When the HTTP handler receives a request, it can read the session ID of the user from the cookie and retrieve any required state.\n\nYou can implement session cookies yourself, or use an existing library.\n\n:::tip\nCookies are often used for authentication as well as for sessions.\n:::\n\nThis example uses the https://github.com/alexedwards/scs library to implement per-user sessions.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/alexedwards/scs/v2\"\n)\n\ntype GlobalState struct {\n\tCount int\n}\n\nvar global GlobalState\n// highlight-next-line\nvar sessionManager *scs.SessionManager\n\nfunc getHandler(w http.ResponseWriter, r *http.Request) {\n\t// highlight-next-line\n\tuserCount := sessionManager.GetInt(r.Context(), \"count\")\n\tcomponent := page(global.Count, userCount)\n\tcomponent.Render(r.Context(), w)\n}\n\nfunc postHandler(w http.ResponseWriter, r *http.Request) {\n\t// Update state.\n\tr.ParseForm()\n\n\t// Check to see if the global button was pressed.\n\tif r.Form.Has(\"global\") {\n\t\tglobal.Count++\n\t}\n\t// highlight-start\n\tif r.Form.Has(\"user\") {\n\t\tcurrentCount := sessionManager.GetInt(r.Context(), \"count\")\n\t\tsessionManager.Put(r.Context(), \"count\", currentCount+1)\n\t}\n\t// highlight-end\n\n\t// Display the form.\n\tgetHandler(w, r)\n}\n\nfunc main() {\n\t// highlight-start\n\t// Initialize the session.\n\tsessionManager = scs.New()\n\tsessionManager.Lifetime = 24 * time.Hour\n\t// highlight-end\n\n\tmux := http.NewServeMux()\n\n\t// Handle POST and GET requests.\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.Method == http.MethodPost {\n\t\t\tpostHandler(w, r)\n\t\t\treturn\n\t\t}\n\t\tgetHandler(w, r)\n\t})\n\n\t// highlight-start\n\t// Add the middleware.\n\tmuxWithSessionMiddleware := sessionManager.LoadAndSave(mux)\n\t// highlight-end\n\n\t// Start the server.\n\tfmt.Println(\"listening on http://localhost:8000\")\n\tif err := http.ListenAndServe(\"localhost:8000\", muxWithSessionMiddleware); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\n:::note\nIncrementing a count by reading and setting the value is not an atomic operation (not thread-safe). In a production application, to increment a per-user count you may wish to use a database that provides a transactional increment operation.\n:::\n\n:::note\nThe default behaviour of `scs` is to store session data in RAM, which isn't suitable for stateless function deployments, or load-balanced applications, but the library supports a range of backend storage solutions.\n:::\n\nComplete source code including AWS CDK code to set up the infrastructure is available at https://github.com/a-h/templ/tree/main/examples/counter\n"
  },
  {
    "path": "docs/docs/05-server-side-rendering/03-htmx.md",
    "content": "# htmx\n\n[htmx](https://htmx.org) can be used to selectively replace content within a web page, instead of replacing the whole page in the browser. This avoids \"full-page postbacks\", where the whole of the browser window is updated when a button is clicked, and results in a better user experience by reducing screen \"flicker\", or losing scroll position.\n\n## Usage\n\nUsing htmx requires:\n\n* Installation of the htmx client-side library.\n* Modifying the HTML markup to instruct the library to perform partial screen updates.\n\n## Installation\n\nTo install the htmx library, download the `htmx.min.js` file and serve it via HTTP.\n\nThen add a `<script>` tag to the `<head>` section of your HTML with the `src` attribute pointing at the file.\n\n```html\n<script src=\"/assets/js/htmx.min.js\"></script>\n```\n\n:::info\nAdvanced htmx installation and usage help is covered in the user guide at https://htmx.org.\n:::\n\n## Count example\n\nTo update the counts on the page without a full postback, the `hx-post=\"/\"` and `hx-select=\"#countsForm\"` attributes must be added to the `<form>` element, along with an `id` attribute to uniquely identify the element.\n\nAdding these attributes instructs the htmx library to replace the browser's HTTP form POST and subsequent refresh with a request from htmx instead. htmx issues a HTTP POST operation to the `/` endpoint, and replaces the `<form>` element with the HTML that is returned.\n\nThe `/` endpoint returns a complete HTML page instead of just the updated `<form>` element HTML. The `hx-select=\"#countsForm\"` instructs htmx to extract the HTML content within the `countsForm` element that is returned by the web server to replace the `<form>` element.\n\n```templ title=\"components/components.templ\"\ntempl counts(global, session int) {\n\t// highlight-next-line\n\t<form id=\"countsForm\" action=\"/\" method=\"POST\" hx-post=\"/\" hx-select=\"#countsForm\" hx-swap=\"outerHTML\">\n\t\t<div class=\"columns\">\n\t\t\t<div class={ \"column\", \"has-text-centered\", \"is-primary\", border }>\n\t\t\t\t<h1 class=\"title is-size-1 has-text-centered\">{ strconv.Itoa(global) }</h1>\n\t\t\t\t<p class=\"subtitle has-text-centered\">Global</p>\n\t\t\t\t<div><button class=\"button is-primary\" type=\"submit\" name=\"global\" value=\"global\">+1</button></div>\n\t\t\t</div>\n\t\t\t<div class={ \"column\", \"has-text-centered\", border }>\n\t\t\t\t<h1 class=\"title is-size-1 has-text-centered\">{ strconv.Itoa(session) }</h1>\n\t\t\t\t<p class=\"subtitle has-text-centered\">Session</p>\n\t\t\t\t<div><button class=\"button is-secondary\" type=\"submit\" name=\"session\" value=\"session\">+1</button></div>\n\t\t\t</div>\n\t\t</div>\n\t</form>\n}\n```\n\nThe example can be viewed at https://d3qfg6xxljj3ky.cloudfront.net\n\nComplete source code including AWS CDK code to set up the infrastructure is available at https://github.com/a-h/templ/tree/main/examples/counter\n\n## Using hx-on attributes\n\nhtmx supports inline JavaScript event handlers using the `hx-on:*` attributes such as `hx-on:click`, `hx-on:submit`, etc.\n\nAttributes starting with `on` or `hx-on:` are treated as script attributes and expect a `templ.ComponentScript` type.\n\nFor static JavaScript, use a string literal:\n\n```templ\n<button hx-on:click=\"alert('Hello')\">Click me</button>\n```\n\nFor dynamic JavaScript with server-side data, use `templ.JSFuncCall`:\n\n```templ\n<script>\n\tfunction showMessage(msg) {\n\t\talert(msg);\n\t}\n</script>\n<button hx-on:click={ templ.JSFuncCall(\"showMessage\", \"Hello from Go\") }>Click me</button>\n```\n"
  },
  {
    "path": "docs/docs/05-server-side-rendering/04-datastar.md",
    "content": "# Datastar\n\n[Datastar](https://data-star.dev) is a hypermedia framework for building reactive web apps. With reactive signals and DOM patching (using a morphing strategy), Datastar allows you to build everything from simple sites to real-time collaborative web apps.\n\n## Usage\n\nUsing Datastar requires:\n\n- Installation of the Datastar client-side library.\n- Modifying the HTML markup to instruct the library to perform DOM patches.\n\n## Installation\n\nDatastar can be installed by adding a `script` tag to your HTML. See the [installation instructions](https://data-star.dev/guide/getting_started#installation).\n\n## Example Project\n\n[Northstar](https://github.com/zangster300/northstar) is a boilerplate project for building real-time hypermedia applications with Datastar. All of the [examples](https://github.com/zangster300/northstar/tree/main/features) use templ.\n\n## Counter Example\n\nWe are going to modify the [templ counter example](example-counter-application) to use Datastar, as per the [example on the site](https://data-star.dev/examples/templ_counter).\n\n### Frontend\n\nFirst, define some HTML with two buttons. One to update a global state, and one to update a per-user state.\n\n```templ title=\"components.templ\"\npackage site\n\nimport \"github.com/starfederation/datastar-go/datastar\"\n\ntype TemplCounterSignals struct {\n\tGlobal uint32 `json:\"global\"`\n\tUser   uint32 `json:\"user\"`\n}\n\ntempl templCounterExampleButtons() {\n\t<div>\n\t\t<button\n\t\t\tdata-on:click=\"@post('/examples/templ_counter/increment/global')\" \n\t\t>\n\t\t\tIncrement Global\n\t\t</button>\n\t\t<button\n\t\t\tdata-on:click={ datastar.PostSSE('/examples/templ_counter/increment/user') }\n\t\t\t<!-- Alternative: Using Datastar SDK sugar--> \n\t\t>\n\t\t\tIncrement User\n\t\t</button>\n\t</div>\n}\n\ntempl templCounterExampleCounts() {\n\t<div>\n\t\t<div>\n\t\t\t<div>Global</div>\n\t\t\t<div data-text=\"$global\"></div>\n\t\t</div>\n\t\t<div>\n\t\t\t<div>User</div>\n\t\t\t<div data-text=\"$user\"></div>\n\t\t</div>\n\t</div>\n}\n\ntempl templCounterExampleInitialContents(signals TemplCounterSignals) {\n\t<div\n\t\tid=\"container\"\n\t\tdata-signals={ templ.JSONString(signals) }\n\t>\n\t\t@templCounterExampleButtons()\n\t\t@templCounterExampleCounts()\n\t</div>\n}\n```\n\n:::tip\nNote that Datastar sends all[^1] signals to the server (as JSON) on each request. This means far less bookkeeping and more predictable state management than when using html forms. \n:::\n\n:::note\n[`data-signals`](https://data-star.dev/reference/attributes#data-signals) is a Datastar attribute that patches (adds, updates or removes) one or more signals into the existing signals. In the example, we store `$global` and `$user` when we initially render the container. \n\n`data-on:click=\"@post('/examples/templ_counter/increment/global')\"` is an attribute expression that says \"When this element is clicked, send a POST request to the server to the specified URL\". The `@post` is an action that is a sandboxed function that knows about things like signals.\n\n`data-text=\"$global\"` is an attribute expression that says \"replace the contents of this element with the value of the `global` signal\". This is a reactive signal that will update the page when the value changes, which we'll see in a moment.\n:::\n\n### Backend\n\nNote the use of Datastar's helpers to set up SSE.\n\n```go title=\"examples_templ_counter.go\"\npackage site\n\nimport (\n\t\"net/http\"\n\t\"sync/atomic\"\n\n\t\"github.com/Jeffail/gabs/v2\"\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/gorilla/sessions\"\n\t\"github.com/starfederation/datastar-go/datastar\"\n)\n\nfunc setupExamplesTemplCounter(examplesRouter chi.Router, sessionSignals sessions.Store) error {\n\n\tvar globalCounter atomic.Uint32\n\tconst (\n\t\tsessionKey = \"templ_counter\"\n\t\tcountKey   = \"count\"\n\t)\n\n\tuserVal := func(r *http.Request) (uint32, *sessions.Session, error) {\n\t\tsess, err := sessionSignals.Get(r, sessionKey)\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\n\t\tval, ok := sess.Values[countKey].(uint32)\n\t\tif !ok {\n\t\t\tval = 0\n\t\t}\n\t\treturn val, sess, nil\n\t}\n\n\texamplesRouter.Get(\"/templ_counter/data\", func(w http.ResponseWriter, r *http.Request) {\n\t\tuserVal, _, err := userVal(r)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t}\n\n\t\tsignals := TemplCounterSignals{\n\t\t\tGlobal: globalCounter.Load(),\n\t\t\tUser:   userVal,\n\t\t}\n\n\t\tc := templCounterExampleInitialContents(signals)\n\t\tdatastar.NewSSE(w, r).MergeFragmentTempl(c)\n\t})\n\n\tupdateGlobal := func(signals *gabs.Container) {\n\t\tsignals.Set(globalCounter.Add(1), \"global\")\n\t}\n\n\texamplesRouter.Route(\"/templ_counter/increment\", func(incrementRouter chi.Router) {\n\t\tincrementRouter.Post(\"/global\", func(w http.ResponseWriter, r *http.Request) {\n\t\t\tupdate := gabs.New()\n\t\t\tupdateGlobal(update)\n\n\t\t\tdatastar.NewSSE(w, r).MarshalAndMergeSignals(update)\n\t\t})\n\n\t\tincrementRouter.Post(\"/user\", func(w http.ResponseWriter, r *http.Request) {\n\t\t\tval, sess, err := userVal(r)\n\t\t\tif err != nil {\n\t\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\t}\n\n\t\t\tval++\n\t\t\tsess.Values[countKey] = val\n\t\t\tif err := sess.Save(r, w); err != nil {\n\t\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\t}\n\n\t\t\tupdate := gabs.New()\n\t\t\tupdateGlobal(update)\n\t\t\tupdate.Set(val, \"user\")\n\n\t\t\tdatastar.NewSSE(w, r).MarshalAndMergeSignals(update)\n\t\t})\n\t})\n\n\treturn nil\n}\n```\n\nThe `atomic.Uint32` type stores the global state. The `userVal` function is a helper that retrieves the user's session state. The `updateGlobal` function increments the global state.\n\n:::note\nIn this example, the global state is stored in RAM and will be lost when the web server reboots. To support load-balanced web servers and stateless function deployments, consider storing the state in a data store such as [NATS KV](https://docs.nats.io/using-nats/developer/develop_jetstream/kv).\n:::\n\n### Per-user session state\n\nIn an HTTP application, per-user state information is partitioned by an HTTP cookie. Cookies that identify a user while they're using a site are known as \"session cookies\". When the HTTP handler receives a request, it can read the session ID of the user from the cookie and retrieve any required state.\n\n### Signal-only patching\n\nSince the page's elements aren't changing dynamically, we can use the `MarshalAndMergeSignals` function to send only the signals that have changed. This is a more efficient way to update the page without even needing to send HTML fragments.\n\n:::tip\nDatastar will merge updates to signals similar to a JSON merge patch. This means you can do dynamic partial updates to the store and the page will update accordingly. [Gabs](https://pkg.go.dev/github.com/Jeffail/gabs/v2#section-readme) is used here to handle dynamic JSON in Go.\n:::"
  },
  {
    "path": "docs/docs/05-server-side-rendering/05-streaming.md",
    "content": "# HTTP Streaming\n\nThe default behaviour of the `templ.Handler` is to render the template to a buffer and then write the buffer to the response.\n\nThis ensures that the template has successfully rendered before the response is sent to the client, so that appropriate response codes can be set if the template fails to render, and partial responses are not sent to the client.\n\n## Rendering lifecycle\n\nTypical usage of templ involves collecting data that is used to populate the template, before rendering the template and sending a response.\n\nFor example, executing several database queries, calling an API, or reading from a file, before rendering the template.\n\n```mermaid\nflowchart TD;\n\tr[Request]\n\tq[DB Queries]\n\tq1[Query result]\n\tq2[Query result]\n\ta[API Calls]\n\tapi[API call result]\n\tt[Render template]\n\th[HTML]\n\tresponse[Response]\n\tr-->q;\n\tr-->a;\n\tq-->q1\n\tq-->q2\n\ta-->api\n\tq1-->t\n\tq2-->t\n\tapi-->t\n\tt-->h\n\th-->response;\n```\n\nHowever, if the queries and API calls take a long time, this has an impact on Time to First Byte (TTFB) because the client has to wait for all database queries and API calls to complete before sending the response.\n\nTo improve TTFB, the template can be streamed to the client as soon as the first part of the template is rendered, while the remaining queries and API calls are still in progress, at the cost of not being able to set response codes or headers after the first part of the template is rendered.\n\n## Enabling streaming\n\nStreaming can be enabled by setting the `Streaming` field of the `templ.Handler` to `true` using the `WithStreaming` option.\n\n```go\ntempl.Handler(component, templ.WithStreaming()).ServeHTTP(w, r)\n```\n\nWhen streaming is enabled, sections of the template can be forcefully pushed to the client using the `templ.Flush()` component.\n\nThis enables interesting use cases. For example, here, the `Page` template is rendered with a channel that is populated by a background goroutine.\n\nBy using `templ.Flush()` to create a flushable area, the data is pushed to the client as soon as it is available, rather than waiting for the entire template to render before sending a response.\n\n```templ\ntempl Page(data chan string) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<title>Page</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>Page</h1>\n\t\t\tfor d := range data {\n\t\t\t\t@templ.Flush() {\n\t\t\t\t\t<div>{ d }</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n```\n\nSee https://github.com/a-h/templ/tree/main/examples/streaming for a full example.\n\n## Suspense\n\nMany modern web frameworks use a concept called \"Suspense\" to handle the loading of data and rendering of components.\n\nThis usually involves displaying placeholder content while the data is loading, and then rendering the component when the data is available.\n\nWith JavaScript frontends like React, the lifecycle is usually that the HTML is rendered, the JS loaded, the initial render that displays the placeholder is done, an API call is made back to the server to fetch data, and then the component is rendered.\n\nThis involves a lot of extra HTTP requests, and means that we have to wait until JavaScript is loaded before we can start fetching data.\n\nCombining templ's streaming capability with a new feature in web browsers called \"Declarative Shadow DOM\" means that we can perform the same action in a single HTTP request.\n\n:::note\nReact SSR solutions such as Next.js can also do this on the server, see https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#what-is-streaming\n:::\n\n### Declarative Shadow DOM\n\nFirst, we need to define a new templ component called `Slot`.\n\n```templ\ntempl Slot(name string) {\n\t<slot name={ name }>\n\t\t<div>Loading { name }...</div>\n\t</slot>\n}\n```\n\nThis component is a placeholder that will be replaced by the contents of the slot when the data is available.\n\nNext, we can use a `<template>` element with `shadowrootmode=\"open\"` to create a shadow DOM that allows us to populate the `<slot>` elements with data.\n\nWe need to use `@templ.Flush()` to create a flushable area, so that the data is pushed to the client as soon as it is available, since popluating the slots will take longer to complete.\n\nWe can then use a `for` loop over the channel of data to populate the slots with content, again, flushing the results to the browser when available.\n\nThe result is a simple way to load content after initial page load without the need to use JavaScript.\n\n```templ\ntempl Page(data chan SlotContents) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<title>Page</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>Page</h1>\n\t\t\t@templ.Flush() {\n\t\t\t\t<template shadowrootmode=\"open\">\n\t\t\t\t\t@Slot(\"a\")\n\t\t\t\t\t@Slot(\"b\")\n\t\t\t\t\t@Slot(\"c\")\n\t\t\t\t</template>\n\t\t\t}\n\t\t\tfor sc := range data {\n\t\t\t\t@templ.Flush() {\n\t\t\t\t\t<div slot={ sc.Name }>\n\t\t\t\t\t\t@sc.Contents\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n```\n\n<video loop autoplay controls src=\"/img/shadowdom.webm\" />\n\nSee https://github.com/a-h/templ/tree/main/examples/suspense for a full working example.\n"
  },
  {
    "path": "docs/docs/05-server-side-rendering/_category_.json",
    "content": "{\n  \"position\": 5,\n  \"label\": \"Server-side rendering\"\n}\n"
  },
  {
    "path": "docs/docs/06-static-rendering/01-generating-static-html-files-with-templ.md",
    "content": "# Generating static HTML files with templ\n\ntempl components implement the `templ.Component` interface.\n\nThe interface has a `Render` method which outputs HTML to an `io.Writer` that is passed in.\n\n```go\ntype Component interface {\n\t// Render the template.\n\tRender(ctx context.Context, w io.Writer) error\n}\n```\n\nIn Go, the `io.Writer` interface is implemented by many built-in types in the standard library, including `os.File` (files), `os.Stdout`, and `http.ResponseWriter` (HTTP responses).\n\nThis makes it easy to use templ components in a variety of contexts to generate HTML.\n\nTo render static HTML files using templ component, first create a new Go project.\n\n## Setup project\n\nCreate a new directory.\n\n```bash\nmkdir static-generator\n```\n\nInitialize a new Go project within it.\n\n```bash\ncd static-generator\ngo mod init github.com/a-h/templ-examples/static-generator\n```\n\n## Create a templ file\n\nTo use it, create a `hello.templ` file containing a component.\n\nComponents are functions that contain templ elements, markup, `if`, `switch` and `for` Go expressions.\n\n```templ title=\"hello.templ\"\npackage main\n\ntempl hello(name string) {\n\t<div>Hello, { name }</div>\n}\n```\n\n## Generate Go code from the templ file\n\nRun the `templ generate` command.\n\n```bash\ntempl generate\n```\n\ntempl will generate a `hello_templ.go` file containing Go code.\n\nThis file will contain a function called `hello` which takes `name` as an argument, and returns a `templ.Component` that renders HTML.\n\n```go\nfunc hello(name string) templ.Component {\n  // ...\n}\n```\n\n## Write a program that renders to stdout\n\nCreate a `main.go` file. The program creates a `hello.html` file and uses the component to write HTML to the file.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n)\n\nfunc main() {\n\tf, err := os.Create(\"hello.html\")\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create output file: %v\", err)\n\t}\n\n\terr = hello(\"John\").Render(context.Background(), f)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to write output file: %v\", err)\n\t}\n}\n```\n\n## Run the program\n\nRunning the code will create a file called `hello.html` containing the component's HTML.\n\n```bash\ngo run *.go\n```\n\n```html title=\"hello.html\"\n<div>Hello, John</div>\n```\n"
  },
  {
    "path": "docs/docs/06-static-rendering/02-blog-example.md",
    "content": "# Blog example\n\nThis example demonstrates building a static blog with templ.\n\n## Create a blog template\n\nCreate a template for the site header and site content. Then, create a template for the content page and index page.\n\n```templ title=\"blog.templ\"\npackage main\n\nimport \"path\"\nimport \"github.com/gosimple/slug\"\n\ntempl headerComponent(title string) {\n\t<head><title>{ title }</title></head>\n}\n\ntempl contentComponent(title string, body templ.Component) {\n\t<body>\n\t\t<h1>{ title }</h1>\n\t\t<div class=\"content\">\n\t\t\t@body\n\t\t</div>\n\t</body>\n}\n\ntempl contentPage(title string, body templ.Component) {\n\t<html>\n\t\t@headerComponent(title)\n\t\t@contentComponent(title, body)\n\t</html>\n}\n\ntempl indexPage(posts []Post) {\n\t<html>\n\t\t@headerComponent(\"My Blog\")\n\t\t<body>\n\t\t\t<h1>My Blog</h1>\n\t\t\tfor _, post := range posts {\n\t\t\t\t<div><a href={ templ.SafeURL(path.Join(post.Date.Format(\"2006/01/02\"), slug.Make(post.Title), \"/\")) }>{ post.Title }</a></div>\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n```\n\nIn the Go code, create a `Post` struct to store information about a blog post.\n\n```go\ntype Post struct {\n\tDate    time.Time\n\tTitle   string\n\tContent string\n}\n```\n\nCreate some pretend blog posts.\n\n```go\nposts := []Post{\n\t{\n\t\tDate:  time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC),\n\t\tTitle: \"Happy New Year!\",\n\t\tContent: `New Year is a widely celebrated occasion in the United Kingdom, marking the end of one year and the beginning of another.\n\nTop New Year Activities in the UK include:\n\n* Attending a Hogmanay celebration in Scotland\n* Taking part in a local First-Foot tradition in Scotland and Northern England\n* Setting personal resolutions and goals for the upcoming year\n* Going for a New Year's Day walk to enjoy the fresh start\n* Visiting a local pub for a celebratory toast and some cheer\n`,\n\t},\n\t{\n\t\tDate:  time.Date(2023, time.May, 1, 0, 0, 0, 0, time.UTC),\n\t\tTitle: \"May Day\",\n\t\tContent: `May Day is an ancient spring festival celebrated on the first of May in the United Kingdom, embracing the arrival of warmer weather and the renewal of life.\n\nTop May Day Activities in the UK:\n\n* Dancing around the Maypole, a traditional folk activity\n* Attending local village fetes and fairs\n* Watching or participating in Morris dancing performances\n* Enjoying the public holiday known as Early May Bank Holiday\n`,\n\t},\n}\n```\n\n## Rendering HTML directly\n\nThe example blog posts contain markdown, so we'll use `github.com/yuin/goldmark` to convert the markdown to HTML.\n\nWe can't use a string containing HTML directly in templ, because all strings are escaped in templ. So we'll create an `Unsafe` code component to write the HTML directly to the output writer without first escaping it.\n\n```go\nfunc Unsafe(html string) templ.Component {\n\treturn templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\t_, err = io.WriteString(w, html)\n\t\treturn\n\t})\n}\n```\n\n## Creating the static pages\n\nThe code creates the index page. The code then iterates through the posts, creating an output file for each blog post.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"time\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/gosimple/slug\"\n\t\"github.com/yuin/goldmark\"\n)\n\nfunc main() {\n\t// Output path.\n\trootPath := \"public\"\n\tif err := os.Mkdir(rootPath, 0755); err != nil {\n\t\tlog.Fatalf(\"failed to create output directory: %v\", err)\n\t}\n\n\t// Create an index page.\n\tname := path.Join(rootPath, \"index.html\")\n\tf, err := os.Create(name)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create output file: %v\", err)\n\t}\n\t// Write it out.\n\terr = indexPage(posts).Render(context.Background(), f)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to write index page: %v\", err)\n\t}\n\n\t// Create a page for each post.\n\tfor _, post := range posts {\n\t\t// Create the output directory.\n\t\tdir := path.Join(rootPath, post.Date.Format(\"2006/01/02\"), slug.Make(post.Title))\n\t\tif err := os.MkdirAll(dir, 0755); err != nil && err != os.ErrExist {\n\t\t\tlog.Fatalf(\"failed to create dir %q: %v\", dir, err)\n\t\t}\n\n\t\t// Create the output file.\n\t\tname := path.Join(dir, \"index.html\")\n\t\tf, err := os.Create(name)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to create output file: %v\", err)\n\t\t}\n\n\t\t// Convert the markdown to HTML, and pass it to the template.\n\t\tvar buf bytes.Buffer\n\t\tif err := goldmark.Convert([]byte(post.Content), &buf); err != nil {\n\t\t\tlog.Fatalf(\"failed to convert markdown to HTML: %v\", err)\n\t\t}\n\n\t\t// Create an unsafe component containing raw HTML.\n\t\tcontent := Unsafe(buf.String())\n\n\t\t// Use templ to render the template containing the raw HTML.\n\t\terr = contentPage(post.Title, content).Render(context.Background(), f)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to write output file: %v\", err)\n\t\t}\n\t}\n}\n```\n\n## Results\n\nAfter generating Go code from the templates, and running it with `templ generate` followed by `go run *.go`, the following files will be created.\n\n```\npublic/index.html\npublic/2023/01/01/happy-new-year/index.html\npublic/2023/05/01/may-day/index.html\n```\n\nThe `index.html` contains links to all of the posts.\n\n```html title=\"index.html\"\n<title>\n My Website\n</title>\n<h1>\n My Website\n</h1>\n<div>\n <a href=\"2023/01/01/happy-new-year/\">\n  Happy New Year!\n </a>\n</div>\n<div>\n <a href=\"2023/05/01/may-day/\">\n  May Day\n </a>\n</div>\n```\n\nWhile each content page contains the HTML generated from the markdown, and the surrounding template.\n\n```html title=\"2023/05/01/may-day/index.html\"\n<title>\n May Day\n</title>\n<h1>\n May Day\n</h1>\n<div class=\"content\">\n <p>\n  May Day is an ancient spring festival celebrated on the first of May in the United Kingdom, embracing the arrival of warmer weather and the renewal of life.\n </p>\n <p>\n  Top May Day Activities in the UK:\n </p>\n <ul>\n  <li>\n   Dancing around the Maypole, a traditional folk activity\n  </li>\n  <li>\n   Attending local village fetes and fairs\n  </li>\n  <li>\n   Watching or participating in Morris dancing performances\n  </li>\n  <li>\n   Enjoying the public holiday known as Early May Bank Holiday\n  </li>\n </ul>\n</div>\n```\n\nThe files in the `public` directory can then be hosted in any static website hosting provider.\n"
  },
  {
    "path": "docs/docs/06-static-rendering/03-deploying-static-files.md",
    "content": "# Deploying static files\n\nOnce you have built static HTML files with templ, you can serve them on any static site hosting platform, or use a web server to serve them.\n\nWays you could host your site include:\n\n* Fly.io\n* Netlify\n* Vercel\n* AWS Amplify\n* Firebase Hosting\n\nTypically specialist static hosting services are more cost-effective than VM or Docker-based services, due to the less complex compute and networking requirements.\n\nMost require you to commit your code to a source repository, with a build process being triggered on commit, but Fly.io allows you to deploy easily from the CLI.\n\n## fly.io\n\nFly.io is a provider of hosting that is straightforward to use, and has a generous free tier. Fly.io is Docker-based, so you can easily switch out to a dynamic website if you need to.\n\nFollowing on from the blog example, all that's required is to add a Dockerfile to the project that copies the contents of the `public` directory into the Docker image, followed by running `flyctl launch` to initialize configuration.\n\n```Dockerfile title=\"Dockerfile\"\nFROM pierrezemb/gostatic\nCOPY ./public/ /srv/http/\nENTRYPOINT [\"/goStatic\", \"-port\", \"8080\"]\n```\n\nMore detailed documentation is available at https://fly.io/docs/languages-and-frameworks/static/\n\n"
  },
  {
    "path": "docs/docs/06-static-rendering/_category_.json",
    "content": "{\n  \"position\": 6,\n  \"label\": \"Static rendering\"\n}\n"
  },
  {
    "path": "docs/docs/07-project-structure/01-project-structure.md",
    "content": "# Project structure\n\nThe example counter project demonstrates a way to structure your applications.\n\nhttps://github.com/a-h/templ/tree/main/examples/counter\n\nThe application is divided up into multiple packages, each with its own purpose.\n\n* `cdk` - Infrastructure setup for deploying the application.\n* `components` - templ components.\n* `db` - Database access code used to increment and get counts.\n* `handlers` - HTTP handlers.\n* `lambda` - The AWS Lambda entry point.\n* `services` - Services used by the handlers.\n* `session` - Middleware for implementing HTTP session IDs.\n* `main.go` - Used to run the application locally.\n\n## Application architecture\n\nThe architecture follows a typical \"onion model\" where each layer doesn't know about the layer above it, and each layer is responsible for a specific thing.\n\n```mermaid\ngraph LR\n    handler[HTTP handler] -- uses --> services[Services]\n    services -- use --> db[Database access code]\n    db -- uses --> dynamodb[(DynamoDB)]\n    handler -- renders --> components[Components]\n```\n\n* HTTP Handler\n  * Processes HTTP requests\n  * Does not contain application logic itself\n  * Uses `services` that carry out application logic\n  * Takes the responses from `services` and uses `components` to render HTML\n  * Creates HTTP responses\n* Services\n  * Carries out application logic such as orchestrating API calls, or making database calls\n  * Does not do anything related to HTML or HTTP\n  * Is not aware of the specifics of database calls\n* Database access code\n  * Handles database activity such as inserting and querying records\n  * Ensures that the database representation (`records`) doesn't leak to the service layer\n\nA more complex application may have a `models` package containing plain structs that represent common data structures in the application, such as `User`.\n\n:::tip\nAs with most things, taking the layering approach to an extreme level can have a negative effect. Ask yourself whether what you're doing is really helping to make the code understandable, or is just spreading application logic across lots of files, and making it hard to see the overall structure.\n:::\n\n## Dependency injection\n\nLayering an application in this way can simplify code structure, since the responsibility of each type is clear.\n\nTo ensure that each part of the application is initialized with its dependencies, each struct defines a constructor (the `New` function in this example).\n\nAs per https://go.dev/wiki/CodeReviewComments#interfaces the HTTP handler defines the interface that it's expecting, rather than the service defining its own interface.\n\n```go title=\"handlers/default.go\"\ntype CountService interface {\n\tIncrement(ctx context.Context, it services.IncrementType, sessionID string) (counts services.Counts, err error)\n\tGet(ctx context.Context, sessionID string) (counts services.Counts, err error)\n}\n\nfunc New(log *slog.Logger, cs CountService) *DefaultHandler {\n\treturn &DefaultHandler{\n\t\tLog:          log,\n\t\tCountService: cs,\n\t}\n}\n\ntype DefaultHandler struct {\n\tLog          *slog.Logger\n\tCountService CountService\n}\n```\n\nChanging the signature of `New` to add a new dependency will result in a compilation error that shows you all the affected code in your application.\n\n:::tip\nDependency injection frameworks are not typically used in Go. If you're coming from a language like C# or Java, this may seem unusual to you, but go with it, you don't need one.\n:::\n\n## HTTP layer\n\nThis HTTP handler reads HTTP requests, uses the `CountService` to `Get` or `Increment` the counters, and renders the templ Components.\n\n:::note\nNote that the `View` method uses the templ Components from the `components` directory to render the page.\n:::\n\n```go \"title=\"handlers/default.go\"\nfunc (h *DefaultHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif r.Method == http.MethodPost {\n\t\th.Post(w, r)\n\t\treturn\n\t}\n\th.Get(w, r)\n}\n\nfunc (h *DefaultHandler) Get(w http.ResponseWriter, r *http.Request) {\n\tvar props ViewProps\n\tvar err error\n\tprops.Counts, err = h.CountService.Get(r.Context(), session.ID(r))\n\tif err != nil {\n\t\th.Log.Error(\"failed to get counts\", slog.Any(\"error\", err))\n\t\thttp.Error(w, \"failed to get counts\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\th.View(w, r, props)\n}\n\nfunc (h *DefaultHandler) Post(w http.ResponseWriter, r *http.Request) {\n\tr.ParseForm()\n\n\t// Decide the action to take based on the button that was pressed.\n\tvar it services.IncrementType\n\tif r.Form.Has(\"global\") {\n\t\tit = services.IncrementTypeGlobal\n\t}\n\tif r.Form.Has(\"session\") {\n\t\tit = services.IncrementTypeSession\n\t}\n\n\tcounts, err := h.CountService.Increment(r.Context(), it, session.ID(r))\n\tif err != nil {\n\t\th.Log.Error(\"failed to increment\", slog.Any(\"error\", err))\n\t\thttp.Error(w, \"failed to increment\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// Display the view.\n\th.View(w, r, ViewProps{\n\t\tCounts: counts,\n\t})\n}\n\ntype ViewProps struct {\n\tCounts services.Counts\n}\n\nfunc (h *DefaultHandler) View(w http.ResponseWriter, r *http.Request, props ViewProps) {\n\tcomponents.Page(props.Counts.Global, props.Counts.Session).Render(r.Context(), w)\n}\n```\n\n## Service layer\n\nThe service layer coordinates API and database activity to carry out application logic.\n\n```go title=\"services/count.go\"\ntype Counts struct {\n\tGlobal  int\n\tSession int\n}\n\nfunc (cs Count) Get(ctx context.Context, sessionID string) (counts Counts, err error) {\n\tglobalAndSessionCounts, err := cs.CountStore.BatchGet(ctx, \"global\", sessionID)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"countservice: failed to get counts: %w\", err)\n\t\treturn\n\t}\n\tif len(globalAndSessionCounts) != 2 {\n\t\terr = fmt.Errorf(\"countservice: unexpected counts returned, expected 2, got %d\", len(globalAndSessionCounts))\n\t}\n\tcounts.Global = globalAndSessionCounts[0]\n\tcounts.Session = globalAndSessionCounts[1]\n\treturn\n}\n```\n\nThis allows us to use Go's parallelism features to run operations more efficiently without adding complexity to the HTTP or database code.\n\n```go title=\"services/count.go\"\nfunc (cs Count) Increment(ctx context.Context, it IncrementType, sessionID string) (counts Counts, err error) {\n\t// Work out which operations to do.\n\tvar global, session func(ctx context.Context, id string) (count int, err error)\n\tswitch it {\n\tcase IncrementTypeGlobal:\n\t\tglobal = cs.CountStore.Increment\n\t\tsession = cs.CountStore.Get\n\tcase IncrementTypeSession:\n\t\tglobal = cs.CountStore.Get\n\t\tsession = cs.CountStore.Increment\n\tdefault:\n\t\treturn counts, ErrUnknownIncrementType\n\t}\n\n\t// Run the operations in parallel.\n\tvar wg sync.WaitGroup\n\twg.Add(2)\n\terrs := make([]error, 2)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tcounts.Global, errs[0] = global(ctx, \"global\")\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tcounts.Session, errs[1] = session(ctx, sessionID)\n\t}()\n\twg.Wait()\n\n\treturn counts, errors.Join(errs...)\n}\n```\n\n## Entrypoint\n\nTo wire all of the dependencies together and start up your web server or serverless function handler, your application will require an entrypoint.\n\nIn this example, the code for configuring the HTTP server and HTTP routes is also in the `main.go` because it's a very simple application. In more complex applications, this might be migrated into another package.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/examples/counter/db\"\n\t\"github.com/a-h/templ/examples/counter/handlers\"\n\t\"github.com/a-h/templ/examples/counter/services\"\n\t\"github.com/a-h/templ/examples/counter/session\"\n\t\"golang.org/x/exp/slog\"\n)\n\nfunc main() {\n\tlog := slog.New(slog.NewJSONHandler(os.Stderr))\n\ts, err := db.NewCountStore(os.Getenv(\"TABLE_NAME\"), os.Getenv(\"AWS_REGION\"))\n\tif err != nil {\n\t\tlog.Error(\"failed to create store\", slog.Any(\"error\", err))\n\t\tos.Exit(1)\n\t}\n\tcs := services.NewCount(log, s)\n\th := handlers.New(log, cs)\n\n\tvar secureFlag = true\n\tif os.Getenv(\"SECURE_FLAG\") == \"false\" {\n\t\tsecureFlag = false\n\t}\n\n\t// Add session middleware.\n\tsh := session.NewMiddleware(h, session.WithSecure(secureFlag))\n\n\tserver := &http.Server{\n\t\tAddr:         \"localhost:9000\",\n\t\tHandler:      sh,\n\t\tReadTimeout:  time.Second * 10,\n\t\tWriteTimeout: time.Second * 10,\n\t}\n\n\tfmt.Printf(\"Listening on %v\\n\", server.Addr)\n\tserver.ListenAndServe()\n}\n```\n"
  },
  {
    "path": "docs/docs/07-project-structure/_category_.json",
    "content": "{\n  \"position\": 7,\n  \"label\": \"Project structure\"\n}\n"
  },
  {
    "path": "docs/docs/08-hosting-and-deployment/01-hosting-on-aws-lambda.md",
    "content": "# Hosting on AWS Lambda\n\nAWS Lambda is a great way to host templ applications.\n\nThe example at https://github.com/a-h/templ/tree/main/examples/counter includes AWS CDK code for deploying onto AWS Lambda.\n\nSee the `/cdk` directory for the details.\n\n## Entrypoint\n\nLambda functions require an entrypoint that receives Lambda requests, and returns Lambda responses.\n\nThe https://github.com/akrylysov/algnhsa package provides an adaptor that allows the standard Go HTTP interface to be used.\n\n```go title=\"lambda/main.go\"\npackage main\n\nimport (\n\t\"os\"\n\n\t\"github.com/a-h/templ/examples/counter/db\"\n\t\"github.com/a-h/templ/examples/counter/handlers\"\n\t\"github.com/a-h/templ/examples/counter/services\"\n\t\"github.com/a-h/templ/examples/counter/session\"\n\t\"github.com/akrylysov/algnhsa\"\n\t\"golang.org/x/exp/slog\"\n)\n\nfunc main() {\n\t// Create handlers.\n\tlog := slog.New(slog.NewJSONHandler(os.Stderr))\n\ts, err := db.NewCountStore(os.Getenv(\"TABLE_NAME\"), os.Getenv(\"AWS_REGION\"))\n\tif err != nil {\n\t\tlog.Error(\"failed to create store\", slog.Any(\"error\", err))\n\t\tos.Exit(1)\n\t}\n\tcs := services.NewCount(log, s)\n\th := handlers.New(log, cs)\n\n\t// Add session middleware.\n\tsh := session.NewMiddleware(h)\n\n\t// Start Lambda.\n\talgnhsa.ListenAndServe(sh, nil)\n}\n```\n\n## Building and deploying\n\nCDK provides the `github.com/aws/aws-cdk-go/awscdklambdagoalpha/v2` package (aliased in this code as `awslambdago`) construct.\n\nAll that's required is to pass the path to the directory containing your Lambda function's `main.go` file and CDK will compile the code and deploy it.\n\n```go title=\"cdk/stack.go\"\n// Strip the binary, and remove the deprecated Lambda SDK RPC code for performance.\n// These options are not required, but make cold start faster.\nbundlingOptions := &awslambdago.BundlingOptions{\n  GoBuildFlags: &[]*string{jsii.String(`-ldflags \"-s -w\" -tags lambda.norpc`)},\n}\nf := awslambdago.NewGoFunction(stack, jsii.String(\"handler\"), &awslambdago.GoFunctionProps{\n  Runtime:      awslambda.Runtime_PROVIDED_AL2(),\n  MemorySize:   jsii.Number(1024),\n  Architecture: awslambda.Architecture_ARM_64(),\n  Entry:        jsii.String(\"../lambda\"),\n  Bundling:     bundlingOptions,\n  Environment: &map[string]*string{\n    \"TABLE_NAME\": db.TableName(),\n  },\n})\n// Add a Function URL.\nlambdaURL := f.AddFunctionUrl(&awslambda.FunctionUrlOptions{\n  AuthType: awslambda.FunctionUrlAuthType_NONE,\n})\nawscdk.NewCfnOutput(stack, jsii.String(\"lambdaFunctionUrl\"), &awscdk.CfnOutputProps{\n  ExportName: jsii.String(\"lambdaFunctionUrl\"),\n  Value:      lambdaURL.Url(),\n})\n```\n\n## Static content\n\nTo serve static content such as images alongside Lambda functions that serve HTML or REST API responses, a common pattern is to use a CloudFront distribution that routes traffic to S3 or to the Lambda Function URL, based on the URL structure.\n\n```mermaid\ngraph TD\n    browser[Browser] --> cf[Cloudfront];\n    cf -- HTTP /* --> furl[Lambda Function URL]\n    cf -- HTTP /assets/* --> s3[S3 Assets Bucket]\n    furl --> lservice[Lambda Service]\n    lservice -- API Gateway V2 request/response --> adaptor[algnhsa Adaptor]\n    adaptor -- Go http.Handler request/response --> code[Your code]\n```\n\nThe example CDK stack includes a deployment process that updates the contents of the S3 bucket.\n\n## Deployed example\n\nTo see the deployed sample application running on AWS Lambda, visit https://d3qfg6xxljj3ky.cloudfront.net\n"
  },
  {
    "path": "docs/docs/08-hosting-and-deployment/02-hosting-using-docker.md",
    "content": "# Hosting using Docker\n\nApplications that use templ can be deployed using the same techniques and platforms as any other Go application.\n\nAn example Dockerfile is provided in the https://github.com/a-h/templ/tree/main/examples/counter-basic example.\n\n# Static content\n\n### Adding static content to the Docker container\n\nWeb applications often need to include static content such as CSS, images, and icon files.\n\nThe https://github.com/a-h/templ/tree/main/examples/counter-basic example has an `assets` directory for this purpose.\n\nThe `COPY` instruction in the Dockerfile copies all of the code and the `assets` directory to the container so that it can be served by the application.\n\n```Dockerfile title=\"Dockerfile\"\n# Build.\nFROM golang:1.20 AS build-stage\nWORKDIR /app\nCOPY go.mod go.sum ./\nRUN go mod download\n// highlight-next-line\nCOPY . /app\nRUN CGO_ENABLED=0 GOOS=linux go build -o /entrypoint\n\n# Deploy.\nFROM gcr.io/distroless/static-debian11 AS release-stage\nWORKDIR /\nCOPY --from=build-stage /entrypoint /entrypoint\n// highlight-next-line\nCOPY --from=build-stage /app/assets /assets\nEXPOSE 8080\nUSER nonroot:nonroot\nENTRYPOINT [\"/entrypoint\"]\n```\n\n### Serving static content\n\nOnce the `/assets` directory has been added to the deployment Docker container, the `http.FileServer` function must be used to serve the content.\n\n```go title=\"main.go\"\nfunc main() {\n\t// Initialize the session.\n\tsessionManager = scs.New()\n\tsessionManager.Lifetime = 24 * time.Hour\n\n\tmux := http.NewServeMux()\n\n\t// Handle POST and GET requests.\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.Method == http.MethodPost {\n\t\t\tpostHandler(w, r)\n\t\t\treturn\n\t\t}\n\t\tgetHandler(w, r)\n\t})\n\n\t// Include the static content.\n\t// highlight-next-line\n\tmux.Handle(\"/assets/\", http.StripPrefix(\"/assets/\", http.FileServer(http.Dir(\"assets\"))))\n\n\t// Add the middleware.\n\tmuxWithSessionMiddleware := sessionManager.LoadAndSave(mux)\n\n\t// Start the server.\n\tfmt.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\":8080\", muxWithSessionMiddleware); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\n## Building and running the Docker container locally\n\nBefore you deploy your application to a hosting provider, you can build and run it locally.\n\nFirst, you'll need to build the Docker container image.\n\n```bash\ndocker build -t counter-basic:latest .\n```\n\nThen you can run the container image, making port `8080` on your `localhost` connect through to port `8080` inside the Docker container.\n\n```bash\ndocker run -p 8080:8080 counter-basic:latest\n```\n\nOnce the container starts, you can open a web browser at `localhost:8080` and view the application.\n\n## Example deployment\n\nThe https://github.com/a-h/templ/tree/main/examples/counter-basic example is deployed at https://counter-basic.fly.dev/\n\n:::note\nThis sample application stores the counts in RAM. If the server restarts, all of the information is lost. To avoid this, use a data store such as DynamoDB or Cloud Firestore. See https://github.com/a-h/templ/tree/main/examples/counter for an example of this.\n:::\n\n"
  },
  {
    "path": "docs/docs/08-hosting-and-deployment/_category_.json",
    "content": "{\n  \"position\": 8,\n  \"label\": \"Hosting and deployment\"\n}\n"
  },
  {
    "path": "docs/docs/09-developer-tools/01-cli.md",
    "content": "# CLI\n\n`templ` provides a command line interface. Most users will only need to run the `templ generate` command to generate Go code from `*.templ` files.\n\n```\nusage: templ <command> [<args>...]\n\ntempl - build HTML UIs with Go\n\nSee docs at https://templ.guide\n\ncommands:\n  generate   Generates Go code from templ files\n  fmt        Formats templ files\n  lsp        Starts a language server for templ files\n  info       Displays information about the templ environment\n  version    Prints the version\n```\n\n## Generating Go code from templ files\n\nThe `templ generate` command generates Go code from `*.templ` files in the current directory tree.\n\nThe command provides additional options:\n\n```\nusage: templ generate [<args>...]\n\nGenerates Go code from templ files.\n\nArgs:\n  -path <path>\n    Generates code for all files in path. (default .)\n  -f <file>\n    Optionally generates code for a single file, e.g. -f header.templ\n  -source-map-visualisations\n    Set to true to generate HTML files to visualise the templ code and its corresponding Go code.\n  -include-version\n    Set to false to skip inclusion of the templ version in the generated code. (default true)\n  -include-timestamp\n    Set to true to include the current time in the generated code.\n  -watch\n    Set to true to watch the path for changes and regenerate code.\n  -cmd <cmd>\n    Set the command to run after generating code.\n  -proxy\n    Set the URL to proxy after generating code and executing the command.\n  -proxyport\n    The port the proxy will listen on. (default 7331)\n  -proxybind\n    The address the proxy will listen on. (default 127.0.0.1)\n  -w\n    Number of workers to use when generating code. (default runtime.NumCPUs)\n  -lazy\n    Only generate .go files if the source .templ file is newer.\t\n  -pprof\n    Port to run the pprof server on.\n  -keep-orphaned-files\n    Keeps orphaned generated templ files. (default false)\n  -v\n    Set log verbosity level to \"debug\". (default \"info\")\n  -log-level\n    Set log verbosity level. (default \"info\", options: \"debug\", \"info\", \"warn\", \"error\")\n  -help\n    Print help and exit.\n```\n\nFor example, to generate code for a single file:\n\n```\ntempl generate -f header.templ\n```\n\n## Formatting templ files\n\nThe `templ fmt` command formats template files. You can use this command in different ways:\n\n1. Format all template files in the current directory and subdirectories:\n\n```\ntempl fmt .\n```\n\n2. Format input from stdin and output to stdout:\n\n```\ntempl fmt\n```\n\nAlternatively, you can run `fmt` in CI to ensure that invalidly formatted templatess do not pass CI. This will cause the command\nto exit with unix error-code `1` if any templates needed to be modified.\n\n```\ntempl fmt -fail .\n```\n\nIf `prettierd`, `prettier` or `npx` is found in your `PATH`, `templ fmt` will use prettier to format `script` and `style` elements in files.\n\n## Language Server for IDE integration\n\n`templ lsp` provides a Language Server Protocol (LSP) implementation to support IDE integrations.\n\nThis command isn't intended to be used directly by users, but is used by IDE integrations such as the VSCode extension and by Neovim support.\n\nBy default, `templ lsp` starts its own instance of gopls. However, gopls supports a [shared daemon mode](https://github.com/golang/tools/blob/master/gopls/doc/daemon.md), allowing multiple clients to connect to a single, long-lived instance. You can enable this mode using the `-gopls-remote` flag, which will either connect to an existing shared gopls instance or create one if none is running. This can improve performance and reduce resource usage.\n\nA number of additional options are provided to enable runtime logging and profiling tools.\n\n```\n  -goplsLog string\n        The file to log gopls output, or leave empty to disable logging.\n  -goplsRPCTrace\n        Set gopls to log input and output messages.\n  -gopls-remote\n        Specify remote gopls instance to connect to.\n  -help\n        Print help and exit.\n  -http string\n        Enable http debug server by setting a listen address (e.g. localhost:7474)\n  -log string\n        The file to log templ LSP output to, or leave empty to disable logging.\n  -pprof\n        Enable pprof web server (default address is localhost:9999)\n```\n"
  },
  {
    "path": "docs/docs/09-developer-tools/02-ide-support.md",
    "content": "# IDE support\n\n## Visual Studio Code\n\nThere's a VS Code extension, just make sure you've already installed templ and that it's on your path.\n\n- https://marketplace.visualstudio.com/items?itemName=a-h.templ\n- https://github.com/templ-go/templ-vscode\n\nVSCodium users can find the extension on the Open VSX Registry at https://open-vsx.org/extension/a-h/templ\n\n### Format on Save\n\nInclude the following into your settings.json to activate formatting `.templ` files on save with the\ntempl plugin:\n\n```json\n{\n    \"editor.formatOnSave\": true,\n    \"[templ]\": {\n        \"editor.defaultFormatter\": \"a-h.templ\"\n    },\n}\n```\n\n### Tailwind CSS Intellisense\n\nInclude the following to the settings.json in order to enable autocompletion for Tailwind CSS in `.templ` files:\n\n```json\n{\n  \"tailwindCSS.includeLanguages\": {\n    \"templ\": \"html\"\n  }\n}\n```\n:::note \nTailwind language servers require a tailwind.config.js file to be present in the root of your project. You can create a new config file with `npx tailwindcss init`, or use samples available at https://tailwindcss.com/docs/configuration\n:::\n\n### Emmet HTML completion\n\nInclude the following to the settings.json in order to get smooth HTML completion via emmet (such as expanding `input:button<Tab>` to `<input type=\"button\" value=\"\">`). The emmet plugin is built into vscode and just needs to be activated for `.templ` files:\n\n```json\n{\n  \"emmet.includeLanguages\": {\n    \"templ\": \"html\"\n  }\n}\n```\n\n## Neovim &gt; 0.5.0\n\nA plugin written in VimScript which adds syntax highlighting: [joerdav/templ.vim](https://github.com/Joe-Davidson1802/templ.vim).\n\nFor neovim you can use [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) and install [tree-sitter-templ](https://github.com/vrischmann/tree-sitter-templ) with `:TSInstall templ`.\n\nThe configuration for the templ Language Server is included in [lspconfig](https://github.com/neovim/nvim-lspconfig), [mason](https://github.com/williamboman/mason.nvim),\nand [mason-lspconfig](https://github.com/williamboman/mason-lspconfig.nvim).\n\nThe `templ` command must be in your system path for the LSP to be able to start. Ensure that you can run it from the command line before continuing.\n\nInstalling and configuring the templ LSP is no different to setting up any other Language Server.\n\n```lua\nlocal lspconfig = require(\"lspconfig\")\n\n-- Use a loop to conveniently call 'setup' on multiple servers and\n-- map buffer local keybindings when the language server attaches\n\nlocal servers = { 'gopls', 'ccls', 'cmake', 'tsserver', 'templ' }\nfor _, lsp in ipairs(servers) do\n  lspconfig[lsp].setup({\n    on_attach = on_attach,\n    capabilities = capabilities,\n  })\nend\n```\n\nIn Neovim, you can use the `:LspInfo` command to check which Language Servers (if any) are running. If the expected language server has not started, it could be due to the unregistered templ file extension. \n\nTo resolve this issue, add the following code to your configuration. This is also necessary for other LSPs to \"pick up\" on .templ files.\n\n```lua\nvim.filetype.add({ extension = { templ = \"templ\" } })\n```\n\n## JetBrains\n\nIntelliJ / GoLand language support for templ:\n\n- https://github.com/templ-go/templ-jetbrains\n- https://plugins.jetbrains.com/plugin/23088-templ\n\n##### Other LSPs within .templ files\n\nThese LSPs can be used *in conjunction* with the templ lsp and tree-sitter. Here's how to set them up.\n\n[html-lsp](https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#html) - First make sure you have it installed `:LspInstall html` or find it on the `:Mason` list. \n\n```lua\nlspconfig.html.setup({\n    on_attach = on_attach,\n    capabilities = capabilities,\n    filetypes = { \"html\", \"templ\" },\n})\n```\n\n[htmx-lsp](https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#htmx) - First make sure you have it installed `:LspInstall htmx` or find it on the `:Mason` list. Note with this LSP, it activates after you type `hx-` in an html attribute, because that's how all htmx attributes are written.\n\n```lua\nlspconfig.htmx.setup({\n    on_attach = on_attach,\n    capabilities = capabilities,\n    filetypes = { \"html\", \"templ\" },\n})\n```\n\n[tailwindcss](https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#tailwindcss) - First make sure you have it installed `:LspInstall tailwindcss` or find it on the `:Mason` list.\n\n```lua\nlspconfig.tailwindcss.setup({\n    on_attach = on_attach,\n    capabilities = capabilities,\n    filetypes = { \"templ\", \"astro\", \"javascript\", \"typescript\", \"react\" },\n    settings = {\n      tailwindCSS = {\n        includeLanguages = {\n          templ = \"html\",\n        },\n      },\n    },\n})\n```\n\nInside of your `tailwind.config.js`, you need to tell tailwind to look inside of .templ files and/or .go files.\n\n:::tip\nIf you don't have a `tailwind.config.js` in the root directory of your project, the Tailwind LSP won't activate, and you won't see autocompletion results.\n:::\n\n```js\nmodule.exports = {\n    content: [ \"./**/*.html\", \"./**/*.templ\", \"./**/*.go\", ],\n    theme: { extend: {}, },\n    plugins: [],\n}\n```\n\n### Formatting\n\nWith the templ LSP installed and configured, you can use the following code snippet to format on save:\n\n```lua\nvim.api.nvim_create_autocmd({ \"BufWritePre\" }, { pattern = { \"*.templ\" }, callback = vim.lsp.buf.format })\n```\n`BufWritePre` means that the callback gets ran after you call `:write`.\n\nIf you have multiple LSPs attached to the same buffer, and you have issues with `vim.lsp.buf.format`, you can use this snippet to run `templ fmt` in the same way that you might from the command line.\n\nThis will get the buffer and its corresponding filename, and refresh the buffer after it has been formatted so you don't get out of sync issues.\n\n```lua\nlocal custom_format = function()\n    if vim.bo.filetype == \"templ\" then\n        local bufnr = vim.api.nvim_get_current_buf()\n        local filename = vim.api.nvim_buf_get_name(bufnr)\n        local cmd = \"templ fmt \" .. vim.fn.shellescape(filename)\n\n        vim.fn.jobstart(cmd, {\n            on_exit = function()\n                -- Reload the buffer only if it's still the current buffer\n                if vim.api.nvim_get_current_buf() == bufnr then\n                    vim.cmd('e!')\n                end\n            end,\n        })\n    else\n        vim.lsp.buf.format()\n    end\nend\n```\n\nTo apply this `custom_format` in your neovim configuration as a keybinding, apply it to the `on_attach` function.\n\n```lua\nlocal on_attach = function(client, bufnr)\n    local opts = { buffer = bufnr, remap = false }\n    -- other configuration options\n    vim.keymap.set(\"n\", \"<leader>lf\", custom_format, opts)\nend\n```\n\nTo make this `custom_format` run on save, make the same autocmd from before and replace the callback with `custom_format`. \n\n```lua\nvim.api.nvim_create_autocmd({ \"BufWritePre\" }, { pattern = { \"*.templ\" }, callback = custom_format })\n```\n\nYou can also rewrite the function like so, given that the function will only be executed on .templ files.\n\n```lua\nlocal templ_format = function()\n    local bufnr = vim.api.nvim_get_current_buf()\n    local filename = vim.api.nvim_buf_get_name(bufnr)\n    local cmd = \"templ fmt \" .. vim.fn.shellescape(filename)\n\n    vim.fn.jobstart(cmd, {\n        on_exit = function()\n            -- Reload the buffer only if it's still the current buffer\n            if vim.api.nvim_get_current_buf() == bufnr then\n                vim.cmd('e!')\n            end\n        end,\n    })\nend\n```\n\n:::note\nFormatting `script` and `style` elements in templ files is handed off to prettier.\n\nIf you don't have `prettierd`, `prettier` or `npx` on your path, formatting will not be applied to those elements.\n:::\n\n### Troubleshooting\n\nIf you cannot run `:TSInstall templ`, ensure you have an up-to-date version of [tree-sitter](https://github.com/nvim-treesitter/nvim-treesitter). The [package for templ](https://github.com/vrischmann/tree-sitter-templ) was [added to the main tree-sitter repository](https://github.com/nvim-treesitter/nvim-treesitter/pull/5667) so you shouldn't need to install a separate plugin for it.\n\nIf you still don't get syntax highlighting after it's installed, try running `:TSBufEnable highlight`. If you find that you need to do this every time you open a .templ file, you can run this autocmd to do it for your neovim configuration.\n\n```lua\nvim.api.nvim_create_autocmd(\"BufEnter\", { pattern = \"*.templ\", callback = function() vim.cmd(\"TSBufEnable highlight\") end }) \n```\n\n### Minimal Config\n\nMinimal config with the following features (useful for debugging):\n- [lazy-vim](https://github.com/folke/lazy.nvim): neovim package manager\n- [lsp config](https://github.com/neovim/nvim-lspconfig)\n    - templ-lsp\n    - html-lsp\n    - htmx-lsp\n    - tailwind-lsp\n- [cmp](https://github.com/hrsh7th/nvim-cmp): for autocompletion\n- [tree-sitter](https://github.com/nvim-treesitter/nvim-treesitter): for synx highlighting\n    - [tree sitter templ](https://github.com/vrischmann/tree-sitter-templ)\n\nTo use this config:\n\n* As a permanent setup: Create/replace `init.lua` in your config folder (`~/.config/nvim/`)\n* As a temporary setup: create a new folder in your `.config` (e.g.`~/.config/nvim_test`) and tell neovim to start up with that as the nvim appname `NVIM_APPNAME=nvim_test nvim` (see [neovim docs](https://neovim.io/doc/user/starting.html#%24NVIM_APPNAME) for further explanation.\n\n\n```lua\nlocal lazypath = vim.fn.stdpath(\"data\") .. \"/lazy/lazy.nvim\"\nif not vim.loop.fs_stat(lazypath) then\n  vim.fn.system({\n    \"git\",\n    \"clone\",\n    \"--filter=blob:none\",\n    \"https://github.com/folke/lazy.nvim.git\",\n    \"--branch=stable\", -- latest stable release\n    lazypath,\n  })\nend\nvim.opt.rtp:prepend(lazypath)\nvim.g.mapleader = \" \" -- Make sure to set `mapleader` before lazy so your mappings are correct\n\nrequire(\"lazy\").setup({\n  'neovim/nvim-lspconfig',\n  {\n    -- Autocompletion\n    'hrsh7th/nvim-cmp',\n    dependencies = {\n      'hrsh7th/cmp-nvim-lsp',\n    },\n  },\n  {\n    -- Highlight, edit, and navigate code\n    'nvim-treesitter/nvim-treesitter',\n    dependencies = {\n      'vrischmann/tree-sitter-templ',\n    },\n    build = ':TSUpdate',\n  },\n})\n\nvim.filetype.add({ extension = { templ = \"templ\" } })\n\ncapabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)\nlocal lspconfig = require(\"lspconfig\")\n\nlspconfig.templ.setup{\n  on_attach = on_attach,\n  capabilities = capabilities,\n}\n\nlspconfig.tailwindcss.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = { \"templ\", \"astro\", \"javascript\", \"typescript\", \"react\" },\n  init_options = { userLanguages = { templ = \"html\" } },\n})\n\nlspconfig.html.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = { \"html\", \"templ\" },\n})\n\nlspconfig.htmx.setup({\n  on_attach = on_attach,\n  capabilities = capabilities,\n  filetypes = { \"html\", \"templ\" },\n})\n\nlocal cmp = require 'cmp'\ncmp.setup({\n  mapping = cmp.mapping.preset.insert({\n    ['<C-b>'] = cmp.mapping.scroll_docs(-4),\n    ['<C-f>'] = cmp.mapping.scroll_docs(4),\n    ['<C-Space>'] = cmp.mapping.complete(),\n    ['<C-e>'] = cmp.mapping.abort(),\n    ['<CR>'] = cmp.mapping.confirm({ select = true }),\n  }),\n  sources = cmp.config.sources({\n    { name = 'nvim_lsp' },\n  })\n})\n\nrequire'nvim-treesitter.configs'.setup {\n  ensure_installed = { \"templ\" },\n  sync_install = false,\n  auto_install = true,\n  ignore_install = { \"javascript\" },\n  highlight = {\n    enable = true,\n  },\n}\n```\n\n## Vim\n\nThis requires Vim version 8 or later. Install LSP and autocomplete plugins, using\n[vim-plug](https://github.com/junegunn/vim-plug) or other plugin manager.\n\n_Note_: this example is for [vim-lsp](https://github.com/prabirshrestha/vim-lsp). Other LSP plugins can be also\nbe used, but they need to be configured differently.\n\n```vim\nPlug 'prabirshrestha/vim-lsp'\nPlug 'prabirshrestha/asyncomplete.vim'\nPlug 'prabirshrestha/asyncomplete-lsp.vim'\n```\n\nAdd configuration:\n\n```vim\n\" Register LSP server for Templ.\nau User lsp_setup call lsp#register_server({\n        \\ 'name': 'templ',\n        \\ 'cmd': [$GOPATH . '/bin/templ', 'lsp'],\n        \\ 'allowlist': ['templ'],\n        \\ })\n\nfunction! s:on_lsp_buffer_enabled() abort\n  setlocal signcolumn=yes\n  if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif\n  nmap <buffer> gd <plug>(lsp-definition)\n  nmap <buffer> gs <plug>(lsp-document-symbol-search)\n  nmap <buffer> gS <plug>(lsp-workspace-symbol-search)\n  nmap <buffer> gr <plug>(lsp-references)\n  nmap <buffer> gi <plug>(lsp-implementation)\n  nmap <buffer> gt <plug>(lsp-type-definition)\n  nmap <buffer> <leader>rn <plug>(lsp-rename)\n  nmap <buffer> [g <plug>(lsp-previous-diagnostic)\n  nmap <buffer> ]g <plug>(lsp-next-diagnostic)\n  nmap <buffer> K <plug>(lsp-hover)\n\n  let g:lsp_format_sync_timeout = 1000\n  autocmd! BufWritePre *.templ call execute('LspDocumentFormatSync')\nendfunction\n\naugroup lsp_install\n    au!\n    \" call s:on_lsp_buffer_enabled only for languages that has the server registered.\n    autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()\naugroup END\n```\n\nSee [vim-lsp](https://github.com/prabirshrestha/vim-lsp) for additional configuration options.\n\nConfigure autocomplete, for example:\n\n```vim\ninoremap <expr> <Tab>   pumvisible() ? \"\\<C-n>\" : \"\\<Tab>\"\ninoremap <expr> <S-Tab> pumvisible() ? \"\\<C-p>\" : \"\\<S-Tab>\"\ninoremap <expr> <cr>    pumvisible() ? asyncomplete#close_popup() : \"\\<cr>\"\n```\n\nSee [asyncomplete.vim](https://github.com/prabirshrestha/asyncomplete.vim) for more options.\n\nIf you're also using [deoplete](https://github.com/Shougo/deoplete.nvim), you may need to disable it for templ files to\navoid conflict with `asyncomplete`:\n\n```vim\nautocmd FileType templ call deoplete#custom#buffer_option('auto_complete', v:false)\n```\n\n_Optional_: If you'd like indentation to better match Go outside of `templ` blocks, install:\n\n```\nPlug 'iefserge/templ.vim'\n```\n\n* This plugin also adds [tcomment_vim](https://github.com/tomtom/tcomment_vim) support.\n* This is a fork of [joerdav/templ.vim](https://github.com/Joe-Davidson1802/templ.vim).\n\n## Helix\n\nhttps://helix-editor.com/\n\nHelix has built-in templ support in unstable since https://github.com/helix-editor/helix/pull/8540/commits/084628d3e0c29f4021f53b3e45997ae92033d2d2\n\nIt will be included in official releases after version 23.05.\n\n## Emacs\n\n[templ-ts-mode](https://github.com/danderson/templ-ts-mode) is a major mode for templ files that provides syntax highlighting, indentation, and the other usual major mode things. It is available on [MELPA](https://melpa.org/#/templ-ts-mode) and can be installed like any other Emacs package.\n\nTempl support requires the [tree-sitter parser for Templ](https://github.com/vrischmann/tree-sitter-templ). If the parser is missing, the mode asks you on first use whether you want to download and build it via `treesit-install-language-grammar` (requires git and a C compiler).\n\n## Troubleshooting\n\n### Check that go, gopls and templ are installed and are present in the path\n\n```bash\nwhich go gopls templ\n```\n\nYou should see 3 lines returned, showing the location of each binary:\n\n```\n/run/current-system/sw/bin/go\n/Users/adrian/go/bin/gopls\n/Users/adrian/bin/templ\n```\n\n### Check that you can run the templ binary\n\nRun `templ lsp --help`, you should see help text.\n\n* If you can't run the `templ` command at the command line:\n  * Check that the `templ` binary is within a directory that's in your path (`echo $PATH` for Linux/Mac/WSL, `$env:path` for Powershell).\n  * Update your profile to ensure that the change to your path applies to new shells and processes.\n    * On MacOS / Linux, you may need to update your `~/.zsh_profile`, `~/.bash_profile` or `~/.profile` file.\n    * On Windows, you will need to use the \"Environment Variables\" dialog. For WSL, use the Linux config.\n  * On MacOS / Linux, check that the file is executable and resolve it with `chmod +x /path/to/templ`.\n  * On MacOS, you might need to go through the steps at https://support.apple.com/en-gb/guide/mac-help/mh40616/mac to enable binaries from an \"unidentified developer\" to run.\n* If you're running VS Code using Windows Subsystem for Linux (WSL), then templ must also be installed within the WSL environment, not just inside your Windows environment.\n* If you're running VS Code in a Devcontainer, it must be installed in there.\n\n\n### Enable LSP logging\n\nFor VS Code, use the \"Preferences: Open User Settings (JSON)\" command in VS Code and add the configuration options.\n\n```js\n{\n    // More settings...\n    \"templ.log\": \"/Users/adrian/templ.log\",\n    \"templ.goplsLog\": \"/Users/adrian/gopls.log\",\n    \"templ.http\": \"localhost:7575\",\n    \"templ.goplsRPCTrace\": true,\n    \"templ.pprof\": false,\n    // More stuff...\n}\n```\n\nFor Neovim, configure the LSP command to add the additional command line options.\n\n```lua\nlocal configs = require('lspconfig.configs')\nconfigs.templ = {\n  default_config = {\n    cmd = { \"templ\", \"lsp\", \"-http=localhost:7474\", \"-log=/Users/adrian/templ.log\" },\n    filetypes = { 'templ' },\n    root_dir = nvim_lsp.util.root_pattern(\"go.mod\", \".git\"),\n    settings = {},\n  },\n}\n```\n\nFor IntelliJ, configure the plugin settings `.idea/templ.xml`.\n\n```xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"TemplSettings\">\n    <option name=\"goplsLog\" value=\"$USER_HOME$/gopls.log\" />\n    <option name=\"goplsRPCTrace\" value=\"true\" />\n    <option name=\"http\" value=\"localhost:7575\" />\n    <option name=\"log\" value=\"$USER_HOME$/templ.log\" />\n  </component>\n</project>\n```\n\n### Make a minimal reproduction, and include the logs\n\nThe logs can be quite verbose, since almost every keypress results in additional logging. If you're thinking about submitting an issue, please try and make a minimal reproduction.\n\n### Look at the web server\n\nThe LSP has a `http` argument that starts a web server that can show the internal state of the LSP - in particular, the mapping between templ files and Go source code. The default is `templ lsp -http=localhost:7474`. See the log options above for instructions on how to set it.\n\n### Run templ info\n\nThe `templ info` command outputs information that's useful for debugging issues.\n\n### \"missing metadata for import\" / \"could not import\"\n\nIf you see an error like this coming from gopls:\n\n```\ncould not import strconv (missing metadata for import of \"strconv\") compiler (BrokenImport)\n```\n\nRunning `go mod tidy` in your project usually solves it.\n"
  },
  {
    "path": "docs/docs/09-developer-tools/03-live-reload.md",
    "content": "# Live reload\n\nTo enable live reload on a `templ` app use:\n\n```bash\ntempl generate --watch --proxy=\"http://localhost:8080\" --cmd=\"go run .\"\n```\n\nThis will:\n\n- Automatically re-generate Go code if you change `*.templ` files.\n- Restart the web server if you change `*.go` files.\n- Automatically reload the browser if you change `*.go` or `*.templ` files.\n- Run a HTTP proxy on `localhost:7331` (by default) that proxies requests to your web server (default `http://localhost:8080`).\n\n## Example\n\nCreate `main.go` and `hello.templ` files.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\tcomponent := hello(\"World\")\n\n\thttp.Handle(\"/\", templ.Handler(component))\n\n\tfmt.Println(\"Listening on :8080\")\n\thttp.ListenAndServe(\":8080\", nil)\n}\n```\n\n```templ title=\"hello.templ\"\npackage main\n\ntempl hello(name string) {\n  <body>\n\t    <div>Hello, { name }</div>\n  </body>\n}\n```\n\nRun `templ generate --watch --proxy=\"http://localhost:8080\" --cmd=\"go run .\"`.\n\nObserve that the web server is started, and the browser opens to `http://localhost:7331`.\n\nMake changes to `hello.templ` and `main.go`, and see the changes reflected in the browser without having to press F5.\n\n## How it works\n\n### templ watches files for changes\n\nThe `templ generate --watch` argument tells `templ` to watch for changes to `*.templ` and `*.go` files in the current directory.\n\nWhen a change is detected, `templ` will:\n\n- Automatically generate `*.go` code from your `*.templ` files when you save changes to them.\n- Create text files in the `tmp` directory that is read by generated templ Go code if the `TEMPL_DEV_MODE` enabled.\n  - This means that the Go web server doesn't need to be restarted when changes are made to HTML or text in `*.templ` files, `templ` can read the files at runtime instead.\n  - The web server is only restarted when changes are made to Go code in `*.templ` files.\n\n### templ restarts your server automatically\n\nThe `--cmd` argument tells `templ` to run a command when `*.go` files change, for example:\n\n```bash\ntempl generate --watch --cmd=\"go run .\"\n```\n\nThe command is executed if `*.go` files change, or if any Go code within `*.templ` files change.\n\nYou can run any command you like, e.g. `go build -o app && ./app`, or `air`, or `wgo`.\n\n### templ uses a proxy to auto-reload the browser\n\nThe `--proxy` argument tells `templ` to run a HTTP proxy that proxies requests to your web server.\n\nFor example, if your web server listens on port 8080:\n\n```bash\ntempl generate --watch --cmd=\"go run .\" --proxy=\"http://localhost:8080\"\n```\n\nThis starts a HTTP proxy that proxies requests to your web server (default `http://localhost:7331`). The proxy inserts client-side JavaScript before the `</body>` tag that will cause the browser to reload the window when the app is restarted instead of you having to reload the page manually - no more pressing F5!\n\nBy default, the proxy binds to `127.0.0.1:7331`. You can use `--proxybind` to bind to another address, e.g., `--proxybind=\"0.0.0.0\"`.\n\n:::note\nIn order for templ to successfully inject the reload JavaScript into the HTML response:\n\n- The HTML must have a `<body>` tag.\n- The HTML must be served with a `Content-Type` of `text/html`.\n- The response must be compressed with no compression, or a supported compression algorithm (e.g. gzip).\n:::\n\n### Using HTTPS with the proxy\n\nIf you need to use HTTPS with the proxy (for example, when testing OAuth redirects that require HTTPS), you can provide TLS certificate and key files using the `--proxy-tls-crt` and `--proxy-tls-key` flags:\n\n```bash\ntempl generate --watch --proxy=\"http://localhost:8080\" --cmd=\"go run .\" --proxy-tls-crt=\"./certs/cert.pem\" --proxy-tls-key=\"./certs/key.pem\"\n```\n\nThis will start the proxy on `https://localhost:7331` instead of `http://localhost:7331`.\n\n:::note\n- Both `--proxy-tls-crt` and `--proxy-tls-key` flags must be provided together.\n- The flags can only be used when the `--proxy` flag is also specified.\n- For self-signed certificates on localhost, the browser will show a security warning. You can proceed by clicking \"Advanced\" and then \"Continue\" (or the equivalent for your browser).\n:::\n\n## Live reload process\n\nThe live reload process can be shown in the following diagram:\n\n```mermaid\nsequenceDiagram\n    browser->>templ_proxy: HTTP\n    activate templ_proxy\n    templ_proxy->>app: HTTP\n    activate app\n    app->>templ_proxy: HTML\n    deactivate app\n    templ_proxy->>templ_proxy: add reload script\n    templ_proxy->>browser: HTML\n    deactivate templ_proxy\n    browser->>templ_proxy: SSE request to /_templ/reload/events\n    activate templ_proxy\n    templ_proxy->>generate: run templ generate if *.templ files have changed\n    templ_proxy->>app: restart app if *.go files have changed\n    templ_proxy->>browser: notify browser to reload page\n    deactivate templ_proxy\n```\n\n### Triggering live reload from outside `templ generate --watch`\n\nIf you want to trigger a live reload from outside `templ generate --watch` (e.g. if you're using `air`, `wgo` or another tool to build, but you want to use the templ live reload proxy), you can use the `--notify-proxy` argument.\n\n```bash\ntempl generate --notify-proxy\n```\n\nThis will default to the default templ proxy address of `localhost:7331`, but can be changed with the `--proxybind` and `--proxyport` arguments.\n\n```bash\ntempl generate --notify-proxy --proxybind=\"localhost\" --proxyport=\"8080\"\n```\n\n## Alternatives\n\nIf you don't want to use `templ generate --watch`, you can use other tools to watch for changes and restart the server.\n\n### wgo\n\n[wgo](https://github.com/bokwoon95/wgo):\n\n> Live reload for Go apps. Watch arbitrary files and respond with arbitrary commands. Supports running multiple invocations in parallel.\n\n```\nwgo -file=.go -file=.templ -xfile=_templ.go templ generate :: go run main.go\n```\n\nTo avoid a continuous reloading files ending with `_templ.go` should be skipped via `-xfile`.\n\n### air\n\nAir can also monitor the filesystem for changes, and provides a proxy to automatically reload pages.\n\nIt uses a `toml` configuration file.\n\nSee https://github.com/air-verse/air for details.\n\n#### Example configuration\n\n```toml title=\".air.toml\"\nroot = \".\"\ntmp_dir = \"tmp\"\n\n[build]\n  bin = \"./tmp/main\"\n  cmd = \"templ generate && go build -o ./tmp/main .\"\n  delay = 1000\n  exclude_dir = [\"assets\", \"tmp\", \"vendor\"]\n  exclude_file = []\n  exclude_regex = [\".*_templ.go\"]\n  exclude_unchanged = false\n  follow_symlink = false\n  full_bin = \"\"\n  include_dir = []\n  include_ext = [\"go\", \"tpl\", \"tmpl\", \"templ\", \"html\"]\n  kill_delay = \"0s\"\n  log = \"build-errors.log\"\n  send_interrupt = false\n  stop_on_error = true\n\n[color]\n  app = \"\"\n  build = \"yellow\"\n  main = \"magenta\"\n  runner = \"green\"\n  watcher = \"cyan\"\n\n[log]\n  time = false\n\n[misc]\n  clean_on_exit = false\n\n[proxy]\n  enabled = true\n  proxy_port = 8383\n  app_port = 8282\n```\n"
  },
  {
    "path": "docs/docs/09-developer-tools/04-live-reload-with-other-tools.md",
    "content": "# Live reload with other tools\n\nBrowser live reload allows you to see your changes immediately without having to switch to your browser and press `F5` or `CMD+R`.\n\nHowever, Web projects usually involve multiple build processes, e.g. css bundling, js bundling, alongside templ code generation and Go compilation.\n\nTools like `air` can be used with templ's built-in proxy server to carry out additional steps.\n\n## Example\n\nThis example, demonstrates setting up a live reload environment that integrates:\n\n- [Tailwind CSS](https://tailwindcss.com/) for generating a css bundle.\n- [esbuild](https://esbuild.github.io/) for bundling JavaScript or TypeScript.\n- [air](https://github.com/air-verse/air) for re-building Go source as well as sending a reload event to the `templ` proxy server.\n\n## How does it work\n\ntempl's built-in proxy server automatically refreshes the browser when a file changes. The proxy server injects a script that reloads the page in the browser if a \"reload\" event is sent to the browser by the proxy. See [Live Reload page](/developer-tools/live-reload) for a detailed explanation.\n\n:::tip\nThe live reload JavaScript is only injected by the templ proxy if your HTML file contains a closing `</body>` tag.\n:::\n\nThe \"reload\" event can be triggered in two ways:\n\n- `templ generate --watch` sends the event whenever a \".templ\" file changes.\n- Manually trigger it by sending a HTTP POST request to `/_templ/reload/event` endpoint. The `templ` CLI provides this via `templ generate --notify-proxy`.\n\n:::tip\ntempl proxy server `--watch` mode generates different `_templ.go` files. In `--watch` mode `_templ.txt` files are generated that contain just the text that's in templ files. This is used to skip compilation of the Go code when only the text content changes.\n:::\n\n## Setting up the Makefile\n\nA `Makefile` can be used to run all of the necessary commands in parallel. This is useful for starting all of the watch processes at once.\n\n### templ watch mode\n\nTo start the `templ` proxy server in watch mode, run:\n\n```bash\ntempl generate --watch --proxy=\"http://localhost:8080\" --open-browser=false\n```\n\nThis assumes that your http server is running on `http://localhost:8080`. `--open-browser=false` is to prevent `templ` from opening the browser automatically.\n\n### Tailwind CSS\n\nTailwind can be installed via your preferred package manager. The `@tailwindcss/cli` package requires `tailwindcss` as a local peer dependency, `tailwindcss` cannot be installed globally.\n\n```bash\nnpm install tailwindcss @tailwindcss/cli\n```\n\nTailwind requires some input CSS file, e.g. `input.css` with the following directive:\n\n```css\n@import \"tailwindcss\";\n```\n\nThen you can use the `@tailwindcss/cli` package to generate the css bundle.\n\n```bash\nnpx --yes @tailwindcss/cli -i ./input.css -o ./assets/styles.css --minify --watch\n```\n\nThis will watch `input.css` as well as your `.templ` files and re-generate `assets/styles.css` whenever there's a change.\n\n### esbuild\n\nTo bundle JavaScript, TypeScript, JSX, or TSX files, you can use `esbuild`:\n\n```bash\nnpx --yes esbuild js/index.ts --bundle --outdir=assets/ --watch\n```\n\nThis will watch `js/index.ts` and relevant files, and re-generate `assets/index.js` whenever there's a change.\n\n### Re-build Go source\n\nTo watch and restart your Go server, when only the `go` files change you can use `air`:\n\n```bash\ngo run github.com/air-verse/air@v1.63.0 \\\n  --build.cmd \"go build -o tmp/bin/main\" --build.bin \"tmp/bin/main\" --build.delay \"100\" \\\n  --build.exclude_dir \"node_modules\" \\\n  --build.include_ext \"go\" \\\n  --build.stop_on_error \"false\" \\\n  --misc.clean_on_exit true\n```\n\n:::tip\nUsing `go run` directly allows the version of `air` to be specified. This ensures that the version of `air` is consistent between machines. In addition, you don't need to run `air init` to generate `.air.toml`.\n:::\n\n:::note\nThis command doesn't do anything to restart or send a reload event to the `templ` proxy server. We'll use a separate `air` command to trigger a notify event when any non-go related files change.\n:::\n\n### Reload event\n\nWe also want the browser to automatically reload when the:\n\n1. HTML content changes\n2. CSS bundle changes\n3. JavaScript bundle changes\n\nTo trigger the event, we can use the `air` command to use a different set of options, using the `templ` CLI to send a reload event to the browser.\n\n```bash\ngo run github.com/air-verse/air@v1.63.0 \\\n  --build.cmd \"templ generate --notify-proxy\" \\\n  --build.bin \"true\" \\\n  --build.delay \"100\" \\\n  --build.exclude_dir \"\" \\\n  --build.include_dir \"assets\" \\\n  --build.include_ext \"js,css\"\n```\n\n:::note\nThe `build.bin` option is set to use the `true` command instead of executing the output of the `build.cmd` option, because the `templ generate --notify-proxy` command doesn't build anything, it just sends a reload event to the `templ` proxy server.\n\n`true` is a command that exits with a zero status code, so you might see `Process Exit with Code 0` printed to the console.\n:::\n\n### Serving static assets\n\nWhen using live reload, static assets must be served directly from the filesystem instead of being embedded in the Go binary, because the Go binary won't be re-built when the assets change.\n\nIn practice this means using `http.Dir` instead of `http.FS` to serve your assets.\n\nIf you don't want to do this, you can add additional asset file extensions to the `--build.include_ext` argument of the `air` command that rebuilds Go code to force a recompilation and restart of the Go server when the assets change.\n\n#### Before\n\n```go\n//go:embed assets/*\nvar assets embed.FS\n...\nmux.Handle(\"/assets/\", http.FileServer(http.FS(assets)))\n```\n\n#### After\n\n```go\nmux.Handle(\"/assets/\", \n  http.StripPrefix(\"/assets\", \n    http.FileServer(http.Dir(\"assets\"))))\n```\n\n:::tip\nWeb browsers will cache assets when they receive a HTTP 304 response. This will result in asset changes not being visible within your application.\n\nTo avoid this, set the `Cache-Control` header to `no-store` for assets in development mode:\n\n```go\nvar dev = true\n\nfunc disableCacheInDevMode(next http.Handler) http.Handler {\n\tif !dev {\n\t\treturn next\n\t}\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Header().Set(\"Cache-Control\", \"no-store\")\n\t\tnext.ServeHTTP(w, r)\n\t})\n}\n\nmux.Handle(\"/assets/\", \n  disableCacheInDevMode(\n    http.StripPrefix(\"/assets\", \n      http.FileServer(http.Dir(\"assets\")))))\n```\n:::\n\n## Putting it all together\n\nA `Makefile` can be used to run all of the commands in parallel.\n\n```make\n# run templ generation in watch mode to detect all .templ files and \n# re-create _templ.txt files on change, then send reload event to browser. \n# Default url: http://localhost:7331\nlive/templ:\n\ttempl generate --watch --proxy=\"http://localhost:8080\" --open-browser=false -v\n\n# run air to detect any go file changes to re-build and re-run the server.\nlive/server:\n\tgo run github.com/air-verse/air@v1.63.0 \\\n\t--build.cmd \"go build -o tmp/bin/main\" --build.bin \"tmp/bin/main\" --build.delay \"100\" \\\n\t--build.exclude_dir \"node_modules\" \\\n\t--build.include_ext \"go\" \\\n\t--build.stop_on_error \"false\" \\\n\t--misc.clean_on_exit true\n\n# run tailwindcss to generate the styles.css bundle in watch mode.\nlive/tailwind:\n\tnpx --yes tailwindcss -i ./input.css -o ./assets/styles.css --minify --watch\n\n# run esbuild to generate the index.js bundle in watch mode.\nlive/esbuild:\n\tnpx --yes esbuild js/index.ts --bundle --outdir=assets/ --watch\n\n# watch for any js or css change in the assets/ folder, then reload the browser via templ proxy.\nlive/sync_assets:\n\tgo run github.com/air-verse/air@v1.63.0 \\\n\t--build.cmd \"templ generate --notify-proxy\" \\\n\t--build.bin \"true\" \\\n\t--build.delay \"100\" \\\n\t--build.exclude_dir \"\" \\\n\t--build.include_dir \"assets\" \\\n\t--build.include_ext \"js,css\"\n\n# start all 5 watch processes in parallel.\nlive: \n\tmake -j5 live/templ live/server live/tailwind live/esbuild live/sync_assets\n```\n\n:::note\nThe `-j5` argument to `make` runs all 5 commands in parallel.\n:::\n\nRun `make live` to start all of the watch processes.\n"
  },
  {
    "path": "docs/docs/09-developer-tools/05-llm.md",
    "content": "# Coding assistants / LLMs\n\nTo provide AI coding assistants such as GitHub Copilot, Cursor or similar with help on how to write templ code, the templ project maintains a single file containing documentation for LLMs to read.\n\nYou can find the file at `https://templ.guide/llms.md`.\n\n## LLM tools\n\n### https://github.com/CopilotC-Nvim/CopilotChat.nvim\n\nCopilotChat is a plugin for Neovim that provides a chat interface for GitHub Copilot. It allows you to ask Copilot questions and get responses in real-time.\n\nUse the URL feature to load `https://templ.guide/llms.md`.\n"
  },
  {
    "path": "docs/docs/09-developer-tools/06-cicd.md",
    "content": "# Ensuring templ files have been committed\n\nIt's common practice to commit generated `*_templ.go` files to your source code repository, so that your codebase is always in a state where it can be built and run without needing to run `templ generate`, e.g. by running `go install` on your project, or by importing it as a dependency in another project.\n\nIn your CI/CD pipeline, if you want to check that `templ generate` has been ran on all templ files (with the same version of templ used by the CI/CD pipeline), you can run `templ generate` again.\n\nIf any files have changed, then the pipeline should fail, as this would indicate that the generated files are not up-to-date with the templ files.\n\n```bash\ntempl generate\ngit diff --exit-code\n```\n"
  },
  {
    "path": "docs/docs/09-developer-tools/_category_.json",
    "content": "{\n  \"position\": 9,\n  \"label\": \"Developer tools\"\n}\n"
  },
  {
    "path": "docs/docs/10-security/01-injection-attacks.md",
    "content": "# Injection attacks\n\ntempl is designed to prevent user-provided data from being used to inject vulnerabilities.\n\n`<script>` and `<style>` tags could allow user data to inject vulnerabilities, so variables are not permitted in these sections.\n\n```html\ntempl Example() {\n  <script>\n    function showAlert() {\n      alert(\"hello\");\n    }\n  </script>\n  <style type=\"text/css\">\n    /* Only CSS is allowed */\n  </style>\n}\n```\n\n`onClick` attributes, and other `on*` attributes are used to execute JavaScript. To prevent user data from being unescaped, `on*` attributes accept a `templ.ComponentScript`.\n\n```html\nscript onClickHandler(msg string) {\n  alert(msg);\n}\n\ntempl Example(msg string) {\n  <div onClick={ onClickHandler(msg) }>\n    { \"will be HTML encoded using templ.Escape\" }\n  </div>\n}\n```\n\nStyle attributes cannot be expressions, only constants, to avoid escaping vulnerabilities. templ style templates (`css className()`) should be used instead.\n\n```html\ntempl Example() {\n  <div style={ \"will throw an error\" }></div>\n}\n```\n\nClass names are sanitized by default. A failed class name is replaced by `--templ-css-class-safe-name`. The sanitization can be bypassed using the `templ.SafeClass` function, but the result is still subject to escaping.\n\n```html\ntempl Example() {\n  <div class={ \"unsafe</style&gt;-will-sanitized\", templ.SafeClass(\"&sanitization bypassed\") }></div>\n}\n```\n\nRendered output:\n\n```html\n<div class=\"--templ-css-class-safe-name &amp;sanitization bypassed\"></div>\n```\n\n```html\ntempl Example() {\n  <div>Node text is not modified at all.</div>\n  <div>{ \"will be escaped using templ.EscapeString\" }</div>\n}\n```\n\n`href` attributes must be a `templ.SafeURL` and are sanitized to remove JavaScript URLs unless bypassed.\n\n```html\ntempl Example() {\n  <a href=\"http://constants.example.com/are/not/sanitized\">Text</a>\n  <a href={ templ.URL(\"will be sanitized by templ.URL to remove potential attacks\") }</a>\n  <a href={ templ.SafeURL(\"will not be sanitized by templ.URL\") }</a>\n}\n```\n\nWithin css blocks, property names, and constant CSS property values are not sanitized or escaped.\n\n```css\ncss className() {\n\tbackground-color: #ffffff;\n}\n```\n\nCSS property values based on expressions are passed through `templ.SanitizeCSS` to replace potentially unsafe values with placeholders.\n\n```css\ncss className() {\n\tcolor: { red };\n}\n```\n"
  },
  {
    "path": "docs/docs/10-security/02-content-security-policy.md",
    "content": "# Content security policy\n\n## Nonces\n\nIn templ [script templates](/syntax-and-usage/script-templates#script-templates) are rendered as inline `<script>` tags.\n\nStrict Content Security Policies (CSP) can prevent these inline scripts from executing.\n\nBy setting a nonce attribute on the `<script>` tag, and setting the same nonce in the CSP header, the browser will allow the script to execute.\n\n:::info\nIt's your responsibility to generate a secure nonce. Nonces should be generated using a cryptographically secure random number generator.\n\nSee https://content-security-policy.com/nonce/ for more information.\n:::\n\n## Setting a nonce\n\nThe `templ.WithNonce` function can be used to set a nonce for templ to use when rendering scripts.\n\nIt returns an updated `context.Context` with the nonce set.\n\nIn this example, the `alert` function is rendered as a script element by templ.\n\n```templ title=\"templates.templ\"\npackage main\n\nimport \"context\"\nimport \"os\"\n\nscript onLoad() {\n    alert(\"Hello, world!\")\n}\n\ntempl template() {\n    @onLoad()\n}\n```\n\n```go title=\"main.go\"\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc withNonce(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tnonce := securelyGenerateRandomString()\n\t\tw.Header().Add(\"Content-Security-Policy\", fmt.Sprintf(\"script-src 'nonce-%s'\", nonce))\n\t\t// Use the context to pass the nonce to the handler.\n\t\tctx := templ.WithNonce(r.Context(), nonce)\n\t\tnext.ServeHTTP(w, r.WithContext(ctx))\n\t})\n}\n\nfunc main() {\n\tmux := http.NewServeMux()\n\n\t// Handle template.\n\tmux.HandleFunc(\"/\", templ.Handler(template()))\n\n\t// Apply middleware.\n\twithNonceMux := withNonce(mux)\n\n\t// Start the server.\n\tfmt.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\":8080\", withNonceMux); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\n```html title=\"Output\"\n<script nonce=\"randomly generated nonce\">\n  function __templ_onLoad_5a85() {\n    alert(\"Hello, world!\")\n  }\n</script>\n<script nonce=\"randomly generated nonce\">\n  __templ_onLoad_5a85()\n</script>\n```\n"
  },
  {
    "path": "docs/docs/10-security/03-code-signing.md",
    "content": "# Code signing\n\nBinaries are created by the GitHub Actions workflow at https://github.com/a-h/templ/blob/main/.github/workflows/release.yml\n\nBinaries are signed by cosign. The public key is stored in the repository at https://github.com/a-h/templ/blob/main/cosign.pub\n\nInstructions for key verification at https://docs.sigstore.dev/verifying/verify/\n"
  },
  {
    "path": "docs/docs/10-security/_category_.json",
    "content": "{\n  \"position\": 10,\n  \"label\": \"Security\"\n}\n"
  },
  {
    "path": "docs/docs/11-media/_category_.json",
    "content": "{\n  \"position\": 11,\n  \"label\": \"Media and talks\"\n}\n"
  },
  {
    "path": "docs/docs/11-media/index.md",
    "content": "# Media and talks\n\n# Go Podcast 2024\n\nhttps://gopodcast.dev/episodes/adrian-hesketh-and-joe-davidson-on-templ\n\n# Gophercon 2024\n\nGo Full Stack Server-Side Rendering vs SPAs - Fernando J. Villamarin Diaz, JPMC\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/X30eAwuUgrE?si=agO05C0M_d2TlkdZ\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen></iframe>\n\n# Big Sky Dev Con 2024\n\nCovers the reason for creating templ, how it works, and how to use it.\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/uVKSmR_hBMs?si=yacWP-H43ib_J2d4&amp;start=7635\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen></iframe>\n\n# Go Time\n\n<audio data-theme=\"night\" data-src=\"https://changelog.com/gotime/291/embed\" src=\"https://op3.dev/e/https://cdn.changelog.com/uploads/gotime/291/go-time-291.mp3\" preload=\"none\" class=\"changelog-episode\" controls></audio><p><a href=\"https://changelog.com/gotime/291\">Go Time 291: Go templating using Templ</a> – Listen on <a href=\"https://changelog.com/\">Changelog.com</a></p><script async src=\"//cdn.changelog.com/embed.js\"></script>\n\n# Gophercon UK 2023\n\nThis talk covers Language Server Protocol from the ground up, and how templ's language server works with gopls.\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/EkK8Jxjj95s?si=ZrT26jb-lItk6FiB\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n\n# How To Setup A Golang + Templ Project Structure\n\nThis tutorial shows how to create a simple web app using templ and the echo router.\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/wttTTFVrQiw?si=ri-7Pzsaq53xXwvK\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>\n"
  },
  {
    "path": "docs/docs/12-integrations/01-web-frameworks.md",
    "content": "# Web frameworks\n\nTempl is framework agnostic but that does not mean it can not be used with Go frameworks and other tools.\n\nBelow are some examples of how to use templ with other Go libraries, frameworks and tools, and links to systems that have built-in templ support.\n\n### Chi\n\nSee an example of using https://github.com/go-chi/chi with templ at:\n\nhttps://github.com/a-h/templ/tree/main/examples/integration-chi\n\n### Echo\n\nSee an example of using https://echo.labstack.com/ with templ at:\n\nhttps://github.com/a-h/templ/tree/main/examples/integration-echo\n\n### Gin\n\nSee an example of using https://github.com/gin-gonic/gin with templ at:\n\nhttps://github.com/a-h/templ/tree/main/examples/integration-gin\n\n### Go Fiber\n\nSee an example of using https://github.com/gofiber/fiber with templ at:\n\nhttps://github.com/a-h/templ/tree/main/examples/integration-gofiber\n\n### CSRF Protection\n\nGo 1.25 includes built-in cross-site request forgery (CSRF) protection via `http.CrossOriginProtection`.\n\n```go title=\"main.go\"\npackage main\n\nimport (\n  \"net/http\"\n  \"log\"\n)\n\nfunc main() {\n  r := http.NewServeMux()\n  r.Handle(\"/\", templ.Handler(Form()))\n\n  // Configure CSRF protection with trusted origins.\n  csrfProtection := http.NewCrossOriginProtection()\n  if err := csrfProtection.AddTrustedOrigin(\"http://localhost:8000\"); err != nil {\n    log.Fatalf(\"failed to add trusted origin: %v\", err)\n  }\n\n  http.ListenAndServe(\"localhost:8000\", csrfProtection.Handler(r))\n}\n```\n\nThe built-in protection uses modern browser security headers (Sec-Fetch-Site) and does not require hidden form fields or tokens in your HTML:\n\n```templ title=\"form.templ\"\ntempl Form() {\n  <h1>CSRF Example</h1>\n  <form method=\"post\" action=\"/\">\n    <div>\n      This form is protected by the built-in CSRF protection which uses the Sec-Fetch-Site header.\n    </div>\n    <input type=\"submit\" value=\"Submit\"/>\n  </form>\n}\n```\n\nFor applications requiring Go 1.24 or earlier, you can use the `github.com/gorilla/csrf` library instead.\n\n## Project scaffolding\n\n- Gowebly - https://github.com/gowebly/gowebly\n- Go-blueprint - https://github.com/Melkeydev/go-blueprint\n- Slick - https://github.com/anthdm/slick\n\n## Other templates\n\n### `template/html`\n\nSee [Using with Go templates](../syntax-and-usage/using-with-go-templates)\n"
  },
  {
    "path": "docs/docs/12-integrations/02-internationalization.md",
    "content": "# Internationalization\n\ntempl can be used with 3rd party internationalization libraries.\n\n## ctxi18n\n\nhttps://github.com/invopop/ctxi18n uses the context package to load strings based on the selected locale.\n\nAn example is available at https://github.com/a-h/templ/tree/main/examples/internationalization\n\n### Storing translations\n\nTranslations are stored in YAML files, according to the language.\n\n```yaml title=\"locales/en/en.yaml\"\nen:\n  hello: \"Hello\"\n  select_language: \"Select Language\"\n```\n\n### Selecting the language\n\nHTTP middleware selects the language to load based on the URL path, `/en`, `/de`, etc.\n\n```go title=\"main.go\"\nfunc newLanguageMiddleware(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tlang := \"en\" // Default language\n\t\tpathSegments := strings.Split(r.URL.Path, \"/\")\n\t\tif len(pathSegments) > 1 {\n\t\t\tlang = pathSegments[1]\n\t\t}\n\t\tctx, err := ctxi18n.WithLocale(r.Context(), lang)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"error setting locale: %v\", err)\n\t\t\thttp.Error(w, \"error setting locale\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\tnext.ServeHTTP(w, r.WithContext(ctx))\n\t})\n}\n```\n\n### Using the middleware\n\nThe `ctxi18n.Load` function is used to load the translations, and the middleware is used to set the language.\n\n```go title=\"main.go\"\nfunc main() {\n\tif err := ctxi18n.Load(locales.Content); err != nil {\n\t\tlog.Fatalf(\"error loading locales: %v\", err)\n\t}\n\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/\", templ.Handler(page()))\n\n\twithLanguageMiddleware := newLanguageMiddleware(mux)\n\n\tlog.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\"127.0.0.1:8080\", withLanguageMiddleware); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n```\n\n### Fetching translations in templates\n\nTranslations are fetched using the `i18n.T` function, passing the implicit context that's available in all templ components, and the key for the translation.\n\n```templ\npackage main\n\nimport (\n\t\"github.com/invopop/ctxi18n/i18n\"\n)\n\ntempl page() {\n\t<html>\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<title>{ i18n.T(ctx, \"hello\") }</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>{ i18n.T(ctx, \"hello\") }</h1>\n\t\t\t<h2>{ i18n.T(ctx, \"select_language\") }</h2>\n\t\t\t<ul>\n\t\t\t\t<li><a href=\"/en\">English</a></li>\n\t\t\t\t<li><a href=\"/de\">Deutsch</a></li>\n\t\t\t\t<li><a href=\"/zh-cn\">中文</a></li>\n\t\t\t</ul>\n\t\t</body>\n\t</html>\n}\n```\n"
  },
  {
    "path": "docs/docs/12-integrations/_category_.json",
    "content": "{\n  \"position\": 12,\n  \"label\": \"Integrations\"\n}\n"
  },
  {
    "path": "docs/docs/13-experimental/01-overview.md",
    "content": "# Experimental packages\n\nExperimental Packages for templ are available at https://github.com/templ-go/x/\n\n:::warning\n- Packages in this module are experimental and may be removed at any time.\n- There is no guarantee of compatibility with future versions.\n- There is no guarantee of stability.\n- Use at your own risk.\n:::\n\n## Approval Process\n\nAs of right now, there is no formal approval process for packages to be stabilized and moved into https://github.com/a-h/templ. Feel free to contribute via GitHub discussions at https://github.com/a-h/templ/discussions\n"
  },
  {
    "path": "docs/docs/13-experimental/02-urlbuilder.md",
    "content": "# urlbuilder\n\nA simple URL builder to construct a `templ.SafeURL`.\n\n```templ title=\"component.templ\"\nimport (\n  \"github.com/templ-go/x/urlbuilder\"\n  \"strconv\"\n  \"strings\"\n)\n\ntempl component(o Order) {\n  <a\n    href={ urlbuilder.New(\"https\", \"example.com\").\n    Path(\"orders\").\n    Path(o.ID).\n    Path(\"line-items\").\n    Query(\"page\", strconv.Itoa(1)).\n    Query(\"limit\", strconv.Itoa(10)).\n    Build() }\n  >\n    { strings.ToUpper(o.Name) }\n  </a>\n}\n```\n\nSee [URL Attributes](/syntax-and-usage/attributes#url-attributes) for more information.\n\n## Feedback\n\nPlease leave your feedback on this feature at https://github.com/a-h/templ/discussions/867\n"
  },
  {
    "path": "docs/docs/13-experimental/_category_.json",
    "content": "{\n  \"position\": 13,\n  \"label\": \"Experimental\"\n}\n"
  },
  {
    "path": "docs/docs/14-help-and-community/_category_.json",
    "content": "{\n  \"position\": 14,\n  \"label\": \"Help and community\"\n}\n"
  },
  {
    "path": "docs/docs/14-help-and-community/index.md",
    "content": "# Getting help\n\nFor help from the community, talking about new ideas, and general discussion:\n\n## Slack\n\nUse the #templ channel in the Gopher Slack community.\n\nhttps://invite.slack.golangbridge.org/\n\n## GitHub Discussion\n\nhttps://github.com/a-h/templ/discussions\n"
  },
  {
    "path": "docs/docs/15-component-libraries/_category_.json",
    "content": "{\n  \"position\": 15,\n  \"label\": \"Component Libraries\"\n}\n"
  },
  {
    "path": "docs/docs/15-component-libraries/index.md",
    "content": "# Component Libraries\n\nComponent libraries in the templ ecosystem provide ready-to-use UI elements.\n\n## templUI\n\n![templUI Banner](/img/ecosystem/templui.png)\n\n### About\n\ntemplUI is the premier UI component library built specifically for templ. It combines the type-safety of Go with the interactivity of Alpine.js and the styling power of Tailwind CSS to create beautiful, responsive web applications.\n\n### Features\n\n- **30+ Ready-made Components**: Buttons, cards, modals, charts, and more\n- **Enterprise-Ready**: Built for production with security in mind\n- **CSP Compliant**: Works seamlessly with Content Security Policy\n- **Type-Safe**: Full Go type system integration and checking\n- **Customizable**: Easily adapt to match your brand identity\n\n### Example\n\n```go\nimport \"github.com/axzilla/templui/components\"\n\ntempl ExamplePage() {\n  @components.Button(components.ButtonProps{\n    Text: \"Click me\",\n    IconRight: icons.ArrowRight(icons.IconProps{Size: \"16\"}),\n  })\n}\n```\n\n### Links\n\n- [Documentation](https://templui.io)\n- [GitHub](https://github.com/axzilla/templui)\n- [Quick Start Template](https://github.com/axzilla/templui-quickstart)\n"
  },
  {
    "path": "docs/docs/16-faq/_category_.json",
    "content": "{\n  \"position\": 16,\n  \"label\": \"FAQ\"\n}\n"
  },
  {
    "path": "docs/docs/16-faq/index.md",
    "content": "# FAQ\n\n## How can I migrate from templ version 0.1.x to templ 0.2.x syntax?\n\nVersions of templ &lt;= v0.2.663 include a `templ migrate` command that can migrate v1 syntax to v2.\n\nThe v1 syntax used some extra characters for variable injection, e.g. `{%= name %}` whereas the latest (v2) syntax uses a single pair of braces within HTML, e.g. `{ name }`.\n"
  },
  {
    "path": "docs/docs/go.mod",
    "content": "module github.com/a-h/templ/docs\n\ngo 1.20\n\nrequire github.com/gosimple/slug v1.13.1\n\nrequire github.com/gosimple/unidecode v1.0.1 // indirect\n"
  },
  {
    "path": "docs/docs/go.sum",
    "content": "github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q=\ngithub.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=\ngithub.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o=\ngithub.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=\n"
  },
  {
    "path": "docs/docs/index.md",
    "content": "---\nsidebar_position: 1\n---\n\n# Introduction\n\n## templ - build HTML with Go\n\nCreate components that render fragments of HTML and compose them to create screens, pages, documents, or apps.\n\n* Server-side rendering: Deploy as a serverless function, Docker container, or standard Go program.\n* Static rendering: Create static HTML files to deploy however you choose.\n* Compiled code: Components are compiled into performant Go code.\n* Use Go: Call any Go code, and use standard `if`, `switch`, and `for` statements.\n* No JavaScript: Does not require any client or server-side JavaScript.\n* Great developer experience: Ships with IDE autocompletion.\n\n```templ\npackage main\n\ntempl Hello(name string) {\n  <div>Hello, { name }</div>\n}\n\ntempl Greeting(person Person) {\n  <div class=\"greeting\">\n    @Hello(person.Name)\n  </div>\n}\n```\n"
  },
  {
    "path": "docs/docs/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/gosimple/slug\"\n)\n\ntype Section struct {\n\tName     string\n\tSubItems []string\n}\n\ntype ItemToCreate struct {\n\tName    string\n\tPath    string\n\tIsFile  bool\n\tContent string\n}\n\nfunc main() {\n\tsections := []Section{\n\t\t{Name: \"Quick Start\", SubItems: []string{\"Installation\", \"Creating a simple templ component\", \"Running your first templ application\"}},\n\t\t{Name: \"Syntax and Usage\", SubItems: []string{\"Basic syntax\", \"Expressions\", \"Conditional HTML attribute expressions\", \"Loops\", \"Template composition\", \"CSS style management\"}},\n\t\t{Name: \"Core Concepts\", SubItems: []string{\"Components\", \"Template generation\", \"Conditional rendering\", \"Rendering lists\", \"Code-only components\"}},\n\t\t{Name: \"Components\", SubItems: []string{\"Creating and organizing components\", \"Adding HTML markup and Go code in templ\", \"Configuring components with parameters\"}},\n\t\t{Name: \"Using Go Functions and Variables\", SubItems: []string{}},\n\t\t{Name: \"Server-side Rendering\", SubItems: []string{\"Creating an HTTP server with templ\", \"Example: Counter application\"}},\n\t\t{Name: \"Static Rendering\", SubItems: []string{\"Generating static HTML files with templ\", \"Deploying static files\"}},\n\t\t{Name: \"Hosting and Deployment\", SubItems: []string{\"Hosting on AWS Lambda\", \"Hosting using Docker\"}},\n\t\t{Name: \"Commands and Tools\", SubItems: []string{\"templ generate\", \"templ fmt\", \"templ lsp\"}},\n\t\t{Name: \"Advanced Topics\", SubItems: []string{\"Code-only components\", \"Source maps\", \"Storybook integration\"}},\n\t\t{Name: \"Tutorials and Examples\", SubItems: []string{\"Tutorial: Counter application\", \"Tutorial: Blog application\"}},\n\t\t{Name: \"API Reference\", SubItems: []string{\"templ.Component\", \"templ.Handler\"}},\n\t\t{Name: \"Frequently Asked Questions\", SubItems: []string{}},\n\t\t{Name: \"Contributing and Support\", SubItems: []string{}},\n\t\t{Name: \"Best Practices\", SubItems: []string{\"Keeping templ components pure and avoiding bugs\"}},\n\t\t{Name: \"Conclusion\", SubItems: []string{\"Summary and next steps for learning more about templ\"}},\n\t}\n\n\tvar items []ItemToCreate\n\n\tfor i, section := range sections {\n\t\ti += 1\n\t\tcurrent := ItemToCreate{\n\t\t\tName:   section.Name,\n\t\t\tPath:   fmt.Sprintf(\"%02d-%s\", i+1, slug.Make(section.Name)),\n\t\t\tIsFile: false,\n\t\t}\n\t\titems = append(items, current)\n\n\t\t// Add category.json\n\t\titems = append(items, ItemToCreate{\n\t\t\tPath:    fmt.Sprintf(\"%s/_category_.json\", current.Path),\n\t\t\tIsFile:  true,\n\t\t\tContent: categoryJSON(i+1, section.Name),\n\t\t})\n\n\t\tif len(section.SubItems) == 0 {\n\t\t\tfileItem := ItemToCreate{\n\t\t\t\tName:    section.Name,\n\t\t\t\tPath:    fmt.Sprintf(\"%s/index.md\", current.Path),\n\t\t\t\tIsFile:  true,\n\t\t\t\tContent: fmt.Sprintf(\"# %s\\n\", section.Name),\n\t\t\t}\n\t\t\titems = append(items, fileItem)\n\t\t}\n\t\tfor j, subItem := range section.SubItems {\n\t\t\tfileItem := ItemToCreate{\n\t\t\t\tName:    subItem,\n\t\t\t\tPath:    fmt.Sprintf(\"%s/%02d-%s.md\", current.Path, j+1, slug.Make(subItem)),\n\t\t\t\tIsFile:  true,\n\t\t\t\tContent: fmt.Sprintf(\"# %s\\n\", subItem),\n\t\t\t}\n\t\t\titems = append(items, fileItem)\n\t\t}\n\t}\n\n\tfor _, item := range items {\n\t\tfmt.Println(item.Path)\n\t\tif item.IsFile {\n\t\t\tos.WriteFile(item.Path, []byte(item.Content), 0644)\n\t\t\tcontinue\n\t\t}\n\t\tos.Mkdir(item.Path, 0755)\n\t}\n}\n\nfunc categoryJSON(position int, label string) string {\n\tsw := new(strings.Builder)\n\tenc := json.NewEncoder(sw)\n\tenc.SetIndent(\"\", \"  \")\n\terr := enc.Encode(Category{\n\t\tPosition: position,\n\t\tLabel:    label,\n\t})\n\tif err != nil {\n\t\tpanic(\"failed to create JSON: \" + err.Error())\n\t}\n\treturn sw.String()\n}\n\ntype Category struct {\n\tPosition int    `json:\"position\"`\n\tLabel    string `json:\"label\"`\n}\n"
  },
  {
    "path": "docs/docusaurus.config.js",
    "content": "// @ts-check\n// Note: type annotations allow type checking and IDEs autocompletion\n\nconst lightCodeTheme = require('prism-react-renderer').themes.github;\nconst darkCodeTheme = require('prism-react-renderer').themes.dracula;\n\n/** @type {import('@docusaurus/types').Config} */\nconst config = {\n  title: 'templ docs',\n  tagline: 'A language for writing HTML user interfaces in Go. ',\n  favicon: 'img/favicon.ico',\n\n  // Set the production url of your site here\n  url: 'https://templ.guide',\n  // Set the /<baseUrl>/ pathname under which your site is served\n  // For GitHub pages deployment, it is often '/<projectName>/'\n  baseUrl: '/',\n\n  // GitHub pages deployment config.\n  // If you aren't using GitHub pages, you don't need these.\n  organizationName: 'a-h', // Usually your GitHub org/user name.\n  projectName: 'templ', // Usually your repo name.\n\n  onBrokenLinks: 'throw',\n\n  // Even if you don't use internalization, you can use this field to set useful\n  // metadata like html lang. For example, if your site is Chinese, you may want\n  // to replace \"en\" with \"zh-Hans\".\n  i18n: {\n    defaultLocale: 'en',\n    locales: ['en'],\n  },\n\n  markdown: {\n    mermaid: true,\n    hooks: {\n      onBrokenMarkdownLinks: 'warn',\n    },\n  },\n  themes: ['@docusaurus/theme-mermaid'],\n\n  presets: [\n    [\n      'classic',\n      /** @type {import('@docusaurus/preset-classic').Options} */\n      ({\n        docs: {\n          sidebarPath: require.resolve('./sidebars.js'),\n          routeBasePath: '/',\n          // Please change this to your repo.\n          // Remove this to remove the \"edit this page\" links.\n          editUrl:\n            'https://github.com/a-h/templ/tree/main/docs/',\n        },\n        blog: false,\n        theme: {\n          customCss: require.resolve('./src/css/custom.css'),\n        },\n      }),\n    ],\n  ],\n\n  themeConfig:\n    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n    ({\n      // Replace with your project's social card\n      image: 'img/social-card.jpg',\n      navbar: {\n        logo: {\n          alt: 'Templ Logo',\n          src: 'img/logo.svg',\n        },\n        items: [\n          {\n            type: 'docSidebar',\n            sidebarId: 'tutorialSidebar',\n            position: 'left',\n            label: 'Docs',\n          },\n          {\n            href: 'https://github.com/a-h/templ',\n            label: 'GitHub',\n            position: 'right',\n          },\n        ],\n      },\n      footer: {\n        style: 'dark',\n        copyright: `Copyright © ${new Date().getFullYear()} Adrian Hesketh, Built with Docusaurus.`,\n      },\n      prism: {\n        theme: lightCodeTheme,\n        darkTheme: darkCodeTheme,\n        additionalLanguages: ['nix', 'bash', 'json'],\n      },\n      algolia: {\n        appId: 'PVCVW9GL1Z',\n        apiKey: '0823e4b4272c719b5338ed75843f38ef',\n        indexName: 'templ',\n      },\n    }),\n};\n\nmodule.exports = config;\n"
  },
  {
    "path": "docs/package.json",
    "content": "{\n  \"name\": \"docs\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"docusaurus\": \"docusaurus\",\n    \"start\": \"npm run generate-llms-md && docusaurus start\",\n    \"build\": \"npm run generate-llms-md && docusaurus build\",\n    \"swizzle\": \"docusaurus swizzle\",\n    \"deploy\": \"docusaurus deploy\",\n    \"clear\": \"docusaurus clear\",\n    \"serve\": \"docusaurus serve\",\n    \"write-translations\": \"docusaurus write-translations\",\n    \"write-heading-ids\": \"docusaurus write-heading-ids\",\n    \"generate-llms-md\": \"find docs | grep '.*md$' | xargs cat > ./static/llms.md\"\n  },\n  \"dependencies\": {\n    \"@docusaurus/core\": \"^3.9.2\",\n    \"@docusaurus/preset-classic\": \"^3.9.2\",\n    \"@docusaurus/theme-mermaid\": \"^3.9.2\",\n    \"@mdx-js/react\": \"^3.1.0\",\n    \"clsx\": \"^2.1.1\",\n    \"prism-react-renderer\": \"^2.4.1\",\n    \"react\": \"^18.3.1\",\n    \"react-dom\": \"^18.3.1\"\n  },\n  \"devDependencies\": {\n    \"@docusaurus/module-type-aliases\": \"^3.9.2\",\n    \"@docusaurus/tsconfig\": \"^3.9.2\",\n    \"@types/react\": \"^18.3.3\",\n    \"prismjs\": \"^1.29.0\",\n    \"typescript\": \"~5.5.3\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.5%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"engines\": {\n    \"node\": \">=18.2\"\n  }\n}\n"
  },
  {
    "path": "docs/sidebars.js",
    "content": "/**\n * Creating a sidebar enables you to:\n - create an ordered group of docs\n - render a sidebar for each doc of that group\n - provide next/previous navigation\n\n The sidebars can be generated from the filesystem, or explicitly defined here.\n\n Create as many sidebars as you want.\n */\n\n// @ts-check\n\n/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */\nconst sidebars = {\n  // By default, Docusaurus generates a sidebar from the docs folder structure\n  tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],\n\n  // But you can create a sidebar manually\n  /*\n  tutorialSidebar: [\n    'intro',\n    'hello',\n    {\n      type: 'category',\n      label: 'Tutorial',\n      items: ['tutorial-basics/create-a-document'],\n    },\n  ],\n   */\n};\n\nmodule.exports = sidebars;\n"
  },
  {
    "path": "docs/src/css/custom.css",
    "content": "/**\n * Any CSS included here will be global. The classic template\n * bundles Infima by default. Infima is a CSS framework designed to\n * work well for content-centric websites.\n */\n\n/* You can override the default Infima variables here. */\n:root {\n  --ifm-color-primary: #008391;\n  --ifm-color-primary-dark: #007380;\n  --ifm-color-primary-darker: #006570;\n  --ifm-color-primary-darkest: #005761;\n  --ifm-color-primary-light: #0093A3;\n  --ifm-color-primary-lighter: #00A5B8;\n  --ifm-color-primary-lightest: #00B3C7;\n  --ifm-code-font-size: 95%;\n  --ifm-footer-background-color: #003238;\n  --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);\n}\n\n.footer--dark {\n  --ifm-footer-background-color: #173E42;\n}\n/* For readability concerns, you should choose a lighter palette in dark mode. */\n[data-theme='dark'] {\n  --ifm-color-primary: #DBBC30;\n  --ifm-color-primary-dark: #D0B125;\n  --ifm-color-primary-darker: #BA9E21;\n  --ifm-color-primary-darkest: #A0881C;\n  --ifm-color-primary-light: #E7C946;\n  --ifm-color-primary-lighter: #F1D65F;\n  --ifm-color-primary-lightest: #F7E078;\n  --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);\n}\n"
  },
  {
    "path": "docs/src/theme/prism-include-languages.js",
    "content": "import siteConfig from '@generated/docusaurus.config';\nexport default function prismIncludeLanguages(PrismObject) {\n    const {\n        themeConfig: {\n            prism\n        },\n    } = siteConfig;\n    const {\n        additionalLanguages\n    } = prism;\n    // Prism components work on the Prism instance on the window, while prism-\n    // react-renderer uses its own Prism instance. We temporarily mount the\n    // instance onto window, import components to enhance it, then remove it to\n    // avoid polluting global namespace.\n    // You can mutate PrismObject: registering plugins, deleting languages... As\n    // long as you don't re-assign it\n    globalThis.Prism = PrismObject;\n    additionalLanguages.forEach((lang) => {\n        // eslint-disable-next-line global-require, import/no-dynamic-require\n        require(`prismjs/components/prism-${lang}`);\n    });\n    var go = globalThis.Prism.languages.extend('go', {\n        'keyword': /\\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var|templ|css|script)\\b/,\n    });\n\n    var space = /(?:\\s|\\/\\/.*(?!.)|\\/\\*(?:[^*]|\\*(?!\\/))\\*\\/)/.source;\n    var braces = /(?:\\{(?:\\{(?:\\{[^{}]*\\}|[^{}])*\\}|[^{}])*\\})/.source;\n    var spread = /(?:\\{<S>*\\.{3}(?:(?!\\{)[^{}]|<BRACES>)*\\})/.source;\n\n    /**\n     * @param {string} source\n     * @param {string} [flags]\n     */\n    function re(source, flags) {\n        source = source\n            .replace(/<S>/g, function() {\n                return space;\n            })\n            .replace(/<BRACES>/g, function() {\n                return braces;\n            })\n            .replace(/<SPREAD>/g, function() {\n                return spread;\n            });\n        return RegExp(source, flags);\n    }\n\n    spread = re(spread).source;\n\n\n    globalThis.Prism.languages.templ = globalThis.Prism.languages.extend('markup', go);\n    globalThis.Prism.languages.templ.tag.pattern = re(\n        /<\\/?(?:[\\w.:-]+(?:<S>+(?:[\\w.:$-]+(?:=(?:\"(?:\\\\[\\s\\S]|[^\\\\\"])*\"|'(?:\\\\[\\s\\S]|[^\\\\'])*'|[^\\s{'\"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\\/?)?>/.source\n    );\n\n    globalThis.Prism.languages.templ.tag.inside['tag'].pattern = /^<\\/?[^\\s>\\/]*/;\n    globalThis.Prism.languages.templ.tag.inside['attr-value'].pattern = /=(?!\\{)(?:\"(?:\\\\[\\s\\S]|[^\\\\\"])*\"|'(?:\\\\[\\s\\S]|[^\\\\'])*'|[^\\s'\">]+)/;\n    globalThis.Prism.languages.templ.tag.inside['tag'].inside['class-name'] = /^[A-Z]\\w*(?:\\.[A-Z]\\w*)*$/;\n    globalThis.Prism.languages.templ.tag.inside['comment'] = go['comment'];\n\n    globalThis.Prism.languages.insertBefore('inside', 'attr-name', {\n        'spread': {\n            pattern: re(/<SPREAD>/.source),\n            inside: globalThis.Prism.languages.templ\n        }\n    }, globalThis.Prism.languages.templ.tag);\n\n    globalThis.Prism.languages.insertBefore('inside', 'special-attr', {\n        'script': {\n            // Allow for two levels of nesting\n            pattern: re(/=<BRACES>/.source),\n            alias: 'language-go',\n            inside: {\n                'script-punctuation': {\n                    pattern: /^=(?=\\{)/,\n                    alias: 'punctuation'\n                },\n                rest: globalThis.Prism.languages.templ\n            },\n        }\n    }, globalThis.Prism.languages.templ.tag);\n\n    // The following will handle plain text inside tags\n    var stringifyToken = function(token) {\n        if (!token) {\n            return '';\n        }\n        if (typeof token === 'string') {\n            return token;\n        }\n        if (typeof token.content === 'string') {\n            return token.content;\n        }\n        return token.content.map(stringifyToken).join('');\n    };\n\n    var walkTokens = function(tokens) {\n        var openedTags = [];\n        for (var i = 0; i < tokens.length; i++) {\n            var token = tokens[i];\n            var notTagNorBrace = false;\n\n            if (typeof token !== 'string') {\n                if (token.type === 'tag' && token.content[0] && token.content[0].type === 'tag') {\n                    // We found a tag, now find its kind\n\n                    if (token.content[0].content[0].content === '</') {\n                        // Closing tag\n                        if (openedTags.length > 0 && openedTags[openedTags.length - 1].tagName === stringifyToken(token.content[0].content[1])) {\n                            // Pop matching opening tag\n                            openedTags.pop();\n                        }\n                    } else {\n                        if (token.content[token.content.length - 1].content === '/>') {\n                            // Autoclosed tag, ignore\n                        } else {\n                            // Opening tag\n                            openedTags.push({\n                                tagName: stringifyToken(token.content[0].content[1]),\n                                openedBraces: 0\n                            });\n                        }\n                    }\n                } else if (openedTags.length > 0 && token.type === 'punctuation' && token.content === '{') {\n\n                    // Here we might have entered a templ context inside a tag\n                    openedTags[openedTags.length - 1].openedBraces++;\n\n                } else if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces > 0 && token.type === 'punctuation' && token.content === '}') {\n\n                    // Here we might have left a templ context inside a tag\n                    openedTags[openedTags.length - 1].openedBraces--;\n\n                } else {\n                    notTagNorBrace = true;\n                }\n            }\n            if (notTagNorBrace || typeof token === 'string') {\n                if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces === 0) {\n                    // Here we are inside a tag, and not inside a templ context.\n                    // That's plain text: drop any tokens matched.\n                    var plainText = stringifyToken(token);\n\n                    // And merge text with adjacent text\n                    if (i < tokens.length - 1 && (typeof tokens[i + 1] === 'string' || tokens[i + 1].type === 'plain-text')) {\n                        plainText += stringifyToken(tokens[i + 1]);\n                        tokens.splice(i + 1, 1);\n                    }\n                    if (i > 0 && (typeof tokens[i - 1] === 'string' || tokens[i - 1].type === 'plain-text')) {\n                        plainText = stringifyToken(tokens[i - 1]) + plainText;\n                        tokens.splice(i - 1, 1);\n                        i--;\n                    }\n\n                    tokens[i] = new globalThis.Prism.Token('plain-text', plainText, null, plainText);\n                }\n            }\n\n            if (token.content && typeof token.content !== 'string') {\n                walkTokens(token.content);\n            }\n        }\n    };\n\n    globalThis.Prism.hooks.add('after-tokenize', function(env) {\n        if (env.language !== 'templ') {\n            return;\n        }\n        walkTokens(env.tokens);\n    });\n}\n"
  },
  {
    "path": "docs/static/.nojekyll",
    "content": ""
  },
  {
    "path": "examples/blog/go.mod",
    "content": "module github.com/a-h/templ/examples/blog\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/PuerkitoBio/goquery v1.10.1\n\tgithub.com/a-h/templ v0.3.833\n)\n\nrequire (\n\tgithub.com/andybalholm/cascadia v1.3.3 // indirect\n\tgolang.org/x/net v0.51.0 // indirect\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/blog/go.sum",
    "content": "github.com/PuerkitoBio/goquery v1.10.1 h1:Y8JGYUkXWTGRB6Ars3+j3kN0xg1YqqlwvdTV8WTFQcU=\ngithub.com/PuerkitoBio/goquery v1.10.1/go.mod h1:IYiHrOMps66ag56LEH7QYDDupKXyo5A8qrjIx3ZtujY=\ngithub.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=\ngithub.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=\ngolang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=\ngolang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=\ngolang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=\ngolang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=\ngolang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=\ngolang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=\ngolang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=\ngolang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=\ngolang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=\ngolang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=\ngolang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=\ngolang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=\ngolang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=\ngolang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=\ngolang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=\ngolang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n"
  },
  {
    "path": "examples/blog/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\t// Use a template that doesn't take parameters.\n\thttp.Handle(\"/\", templ.Handler(home()))\n\n\t// Use a template that accesses data or handles form posts.\n\thttp.Handle(\"/posts\", NewPostsHandler())\n\n\t// Start the server.\n\tfmt.Println(\"listening on http://localhost:8000\")\n\tif err := http.ListenAndServe(\"localhost:8000\", nil); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n\nfunc NewPostsHandler() PostsHandler {\n\t// Replace this in-memory function with a call to a database.\n\tpostsGetter := func() (posts []Post, err error) {\n\t\treturn []Post{{Name: \"templ\", Author: \"author\"}}, nil\n\t}\n\treturn PostsHandler{\n\t\tGetPosts: postsGetter,\n\t\tLog:      log.Default(),\n\t}\n}\n\ntype PostsHandler struct {\n\tLog      *log.Logger\n\tGetPosts func() ([]Post, error)\n}\n\nfunc (ph PostsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tps, err := ph.GetPosts()\n\tif err != nil {\n\t\tph.Log.Printf(\"failed to get posts: %v\", err)\n\t\thttp.Error(w, \"failed to retrieve posts\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\ttempl.Handler(posts(ps)).ServeHTTP(w, r)\n}\n\ntype Post struct {\n\tName   string\n\tAuthor string\n}\n"
  },
  {
    "path": "examples/blog/posts.templ",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntempl headerTemplate(name string) {\n\t<header data-testid=\"headerTemplate\">\n\t\t<h1>{ name }</h1>\n\t</header>\n}\n\ntempl footerTemplate() {\n\t<footer data-testid=\"footerTemplate\">\n\t\t<div>&copy; { fmt.Sprintf(\"%d\", time.Now().Year()) }</div>\n\t</footer>\n}\n\ntempl navTemplate() {\n\t<nav data-testid=\"navTemplate\">\n\t\t<ul>\n\t\t\t<li><a href=\"/\">Home</a></li>\n\t\t\t<li><a href=\"/posts\">Posts</a></li>\n\t\t</ul>\n\t</nav>\n}\n\ntempl layout(name string) {\n\t<html>\n\t\t<head><title>{ name }</title></head>\n\t\t<body>\n\t\t\t@headerTemplate(name)\n\t\t\t@navTemplate()\n\t\t\t<main>\n\t\t\t\t{ children... }\n\t\t\t</main>\n\t\t</body>\n\t\t@footerTemplate()\n\t</html>\n}\n\ntempl postsTemplate(posts []Post) {\n\t<div data-testid=\"postsTemplate\">\n\t\tfor _, p := range posts {\n\t\t\t<div data-testid=\"postsTemplatePost\">\n\t\t\t\t<div data-testid=\"postsTemplatePostName\">{ p.Name }</div>\n\t\t\t\t<div data-testid=\"postsTemplatePostAuthor\">{ p.Author }</div>\n\t\t\t</div>\n\t\t}\n\t</div>\n}\n\ntempl home() {\n\t@layout(\"Home\") {\n\t\t<div data-testid=\"homeTemplate\">Welcome to my website.</div>\n\t}\n}\n\ntempl posts(posts []Post) {\n\t@layout(\"Posts\") {\n\t\t@postsTemplate(posts)\n\t}\n}\n"
  },
  {
    "path": "examples/blog/posts_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc headerTemplate(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<header data-testid=\\\"headerTemplate\\\"><h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/blog/posts.templ`, Line: 10, Col: 12}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</h1></header>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc footerTemplate() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<footer data-testid=\\\"footerTemplate\\\"><div>&copy; \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(\"%d\", time.Now().Year()))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/blog/posts.templ`, Line: 16, Col: 52}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</div></footer>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc navTemplate() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<nav data-testid=\\\"navTemplate\\\"><ul><li><a href=\\\"/\\\">Home</a></li><li><a href=\\\"/posts\\\">Posts</a></li></ul></nav>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc layout(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var6 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var6 == nil {\n\t\t\ttempl_7745c5c3_Var6 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<html><head><title>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 string\n\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/blog/posts.templ`, Line: 31, Col: 21}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"</title></head><body>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = headerTemplate(name).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = navTemplate().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<main>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ_7745c5c3_Var6.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"</main></body>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = footerTemplate().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"</html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc postsTemplate(posts []Post) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var8 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var8 == nil {\n\t\t\ttempl_7745c5c3_Var8 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"<div data-testid=\\\"postsTemplate\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor _, p := range posts {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"<div data-testid=\\\"postsTemplatePost\\\"><div data-testid=\\\"postsTemplatePostName\\\">\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var9 string\n\t\t\ttempl_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/blog/posts.templ`, Line: 47, Col: 53}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"</div><div data-testid=\\\"postsTemplatePostAuthor\\\">\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var10 string\n\t\t\ttempl_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(p.Author)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/blog/posts.templ`, Line: 48, Col: 57}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, \"</div></div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc home() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var11 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var11 == nil {\n\t\t\ttempl_7745c5c3_Var11 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Var12 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, \"<div data-testid=\\\"homeTemplate\\\">Welcome to my website.</div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = layout(\"Home\").Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc posts(posts []Post) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var13 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var13 == nil {\n\t\t\ttempl_7745c5c3_Var13 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Var14 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = postsTemplate(posts).Render(ctx, templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = layout(\"Posts\").Render(templ.WithChildren(ctx, templ_7745c5c3_Var14), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/blog/posts_test.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/PuerkitoBio/goquery\"\n)\n\nfunc TestHeader(t *testing.T) {\n\t// Pipe the rendered template into goquery.\n\tr, w := io.Pipe()\n\tgo func() {\n\t\t_ = headerTemplate(\"Posts\").Render(context.Background(), w)\n\t\t_ = w.Close()\n\t}()\n\tdoc, err := goquery.NewDocumentFromReader(r)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read template: %v\", err)\n\t}\n\t// Expect the component to include a testid.\n\tif doc.Find(`[data-testid=\"headerTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected data-testid attribute to be rendered, but it wasn't\")\n\t}\n\t// Expect the page name to be set correctly.\n\texpectedPageName := \"Posts\"\n\tif actualPageName := doc.Find(\"h1\").Text(); actualPageName != expectedPageName {\n\t\tt.Errorf(\"expected page name %q, got %q\", expectedPageName, actualPageName)\n\t}\n}\n\nfunc TestFooter(t *testing.T) {\n\t// Pipe the rendered template into goquery.\n\tr, w := io.Pipe()\n\tgo func() {\n\t\t_ = footerTemplate().Render(context.Background(), w)\n\t\t_ = w.Close()\n\t}()\n\tdoc, err := goquery.NewDocumentFromReader(r)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read template: %v\", err)\n\t}\n\t// Expect the component to include a testid.\n\tif doc.Find(`[data-testid=\"footerTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected data-testid attribute to be rendered, but it wasn't\")\n\t}\n\t// Expect the copyright notice to include the current year.\n\texpectedCopyrightNotice := fmt.Sprintf(\"© %d\", time.Now().Year())\n\tif actualCopyrightNotice := doc.Find(\"div\").Text(); actualCopyrightNotice != expectedCopyrightNotice {\n\t\tt.Errorf(\"expected copyright notice %q, got %q\", expectedCopyrightNotice, actualCopyrightNotice)\n\t}\n}\n\nfunc TestNav(t *testing.T) {\n\tr, w := io.Pipe()\n\tgo func() {\n\t\t_ = navTemplate().Render(context.Background(), w)\n\t\t_ = w.Close()\n\t}()\n\tdoc, err := goquery.NewDocumentFromReader(r)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read template: %v\", err)\n\t}\n\t// Expect the component to include a testid.\n\tif doc.Find(`[data-testid=\"navTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected data-testid attribute to be rendered, but it wasn't\")\n\t}\n}\n\nfunc TestHome(t *testing.T) {\n\tr, w := io.Pipe()\n\tgo func() {\n\t\t_ = home().Render(context.Background(), w)\n\t\t_ = w.Close()\n\t}()\n\tdoc, err := goquery.NewDocumentFromReader(r)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read template: %v\", err)\n\t}\n\t// Expect the page title to be set correctly.\n\texpectedTitle := \"Home\"\n\tif actualTitle := doc.Find(\"title\").Text(); actualTitle != expectedTitle {\n\t\tt.Errorf(\"expected title name %q, got %q\", expectedTitle, actualTitle)\n\t}\n\t// Expect the header to be rendered.\n\tif doc.Find(`[data-testid=\"headerTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected data-testid attribute to be rendered, but it wasn't\")\n\t}\n\t// Expect the navigation to be rendered.\n\tif doc.Find(`[data-testid=\"navTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected nav to be rendered, but it wasn't\")\n\t}\n\t// Expect the home template be rendered.\n\tif doc.Find(`[data-testid=\"homeTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected homeTemplate to be rendered, but it wasn't\")\n\t}\n}\n\nfunc TestPosts(t *testing.T) {\n\ttestPosts := []Post{\n\t\t{Name: \"Name1\", Author: \"Author1\"},\n\t\t{Name: \"Name2\", Author: \"Author2\"},\n\t}\n\tr, w := io.Pipe()\n\tgo func() {\n\t\t_ = posts(testPosts).Render(context.Background(), w)\n\t\t_ = w.Close()\n\t}()\n\tdoc, err := goquery.NewDocumentFromReader(r)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read template: %v\", err)\n\t}\n\t// Assert.\n\t// Expect the page title to be set correctly.\n\texpectedTitle := \"Posts\"\n\tif actualTitle := doc.Find(\"title\").Text(); actualTitle != expectedTitle {\n\t\tt.Errorf(\"expected title name %q, got %q\", expectedTitle, actualTitle)\n\t}\n\t// Expect the header to be rendered.\n\tif doc.Find(`[data-testid=\"headerTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected data-testid attribute to be rendered, but it wasn't\")\n\t}\n\t// Expect the navigation to be rendered.\n\tif doc.Find(`[data-testid=\"navTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected nav to be rendered, but it wasn't\")\n\t}\n\t// Expect the posts to be rendered.\n\tif doc.Find(`[data-testid=\"postsTemplate\"]`).Length() == 0 {\n\t\tt.Error(\"expected posts to be rendered, but it wasn't\")\n\t}\n\t// Expect both posts to be rendered.\n\tif actualPostCount := doc.Find(`[data-testid=\"postsTemplatePost\"]`).Length(); actualPostCount != len(testPosts) {\n\t\tt.Fatalf(\"expected %d posts to be rendered, found %d\", len(testPosts), actualPostCount)\n\t}\n\t// Expect the posts to contain the author name.\n\tdoc.Find(`[data-testid=\"postsTemplatePost\"]`).Each(func(index int, sel *goquery.Selection) {\n\t\texpectedName := testPosts[index].Name\n\t\tif actualName := sel.Find(`[data-testid=\"postsTemplatePostName\"]`).Text(); actualName != expectedName {\n\t\t\tt.Errorf(\"expected name %q, got %q\", actualName, expectedName)\n\t\t}\n\t\texpectedAuthor := testPosts[index].Author\n\t\tif actualAuthor := sel.Find(`[data-testid=\"postsTemplatePostAuthor\"]`).Text(); actualAuthor != expectedAuthor {\n\t\t\tt.Errorf(\"expected author %q, got %q\", actualAuthor, expectedAuthor)\n\t\t}\n\t})\n}\n\nfunc TestPostsHandler(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\tpostGetter     func() (posts []Post, err error)\n\t\texpectedStatus int\n\t\tassert         func(doc *goquery.Document)\n\t}{\n\t\t{\n\t\t\tname: \"database errors result in a 500 error\",\n\t\t\tpostGetter: func() (posts []Post, err error) {\n\t\t\t\treturn nil, errors.New(\"database error\")\n\t\t\t},\n\t\t\texpectedStatus: http.StatusInternalServerError,\n\t\t\tassert: func(doc *goquery.Document) {\n\t\t\t\texpected := \"failed to retrieve posts\\n\"\n\t\t\t\tif actual := doc.Text(); actual != expected {\n\t\t\t\t\tt.Errorf(\"expected error message %q, got %q\", expected, actual)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"database success renders the posts\",\n\t\t\tpostGetter: func() (posts []Post, err error) {\n\t\t\t\treturn []Post{\n\t\t\t\t\t{Name: \"Name1\", Author: \"Author1\"},\n\t\t\t\t\t{Name: \"Name2\", Author: \"Author2\"},\n\t\t\t\t}, nil\n\t\t\t},\n\t\t\texpectedStatus: http.StatusInternalServerError,\n\t\t\tassert: func(doc *goquery.Document) {\n\t\t\t\tif doc.Find(`[data-testid=\"postsTemplate\"]`).Length() == 0 {\n\t\t\t\t\tt.Error(\"expected posts to be rendered, but it wasn't\")\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\t// Arrange.\n\t\tw := httptest.NewRecorder()\n\t\tr := httptest.NewRequest(http.MethodGet, \"/posts\", nil)\n\n\t\tph := NewPostsHandler()\n\t\tph.Log = log.New(io.Discard, \"\", 0) // Suppress logging.\n\t\tph.GetPosts = test.postGetter\n\n\t\t// Act.\n\t\tph.ServeHTTP(w, r)\n\t\tdoc, err := goquery.NewDocumentFromReader(w.Result().Body)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to read template: %v\", err)\n\t\t}\n\n\t\t// Assert.\n\t\ttest.assert(doc)\n\t}\n}\n"
  },
  {
    "path": "examples/content-security-policy/main.go",
    "content": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"log/slog\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\tlog := slog.New(slog.NewJSONHandler(os.Stderr, nil))\n\n\t// Create HTTP routes.\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/\", templ.Handler(template()))\n\n\t// Wrap the router with CSP middleware to apply the CSP nonce to templ scripts.\n\twithCSPMiddleware := NewCSPMiddleware(log, mux)\n\n\tlog.Info(\"Listening...\", slog.String(\"addr\", \"127.0.0.1:7001\"))\n\tif err := http.ListenAndServe(\"127.0.0.1:7001\", withCSPMiddleware); err != nil {\n\t\tlog.Error(\"failed to start server\", slog.Any(\"error\", err))\n\t}\n}\n\nfunc NewCSPMiddleware(log *slog.Logger, next http.Handler) *CSPMiddleware {\n\treturn &CSPMiddleware{\n\t\tLog:  log,\n\t\tNext: next,\n\t\tSize: 28,\n\t}\n}\n\ntype CSPMiddleware struct {\n\tLog  *slog.Logger\n\tNext http.Handler\n\tSize int\n}\n\nfunc (m *CSPMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tnonce, err := m.generateNonce()\n\tif err != nil {\n\t\tm.Log.Error(\"failed to generate nonce\", slog.Any(\"error\", err))\n\t\thttp.Error(w, \"Internal server error\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tctx := templ.WithNonce(r.Context(), nonce)\n\tw.Header().Add(\"Content-Security-Policy\", fmt.Sprintf(\"script-src 'nonce-%s'\", nonce))\n\tm.Next.ServeHTTP(w, r.WithContext(ctx))\n}\n\nfunc (m *CSPMiddleware) generateNonce() (string, error) {\n\tconst letters = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-\"\n\tret := make([]byte, m.Size)\n\tfor i := range m.Size {\n\t\tnum, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tret[i] = letters[num.Int64()]\n\t}\n\treturn string(ret), nil\n}\n"
  },
  {
    "path": "examples/content-security-policy/templates.templ",
    "content": "package main\n\nscript sayHello() {\n\talert(\"Hello\")\n}\n\ntempl template() {\n\t@sayHello()\n}\n"
  },
  {
    "path": "examples/content-security-policy/templates_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc sayHello() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_sayHello_6bd3`,\n\t\tFunction: `function __templ_sayHello_6bd3(){alert(\"Hello\")\n}`,\n\t\tCall:       templ.SafeScript(`__templ_sayHello_6bd3`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_sayHello_6bd3`),\n\t}\n}\n\nfunc template() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = sayHello().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/counter/Dockerfile",
    "content": "FROM pierrezemb/gostatic\nCOPY ./public/ /srv/http/\nENTRYPOINT [\"/goStatic\", \"-port\", \"8080\"]\n"
  },
  {
    "path": "examples/counter/README.md",
    "content": "## Tasks\n\n### generate\n\n```sh\ntempl generate\n```\n\n### deploy\n\nrequires: generate\ndir: cdk\n\n```sh\ncdk deploy\n```\n\n### deploy-hotswap\n\nrequires: generate\ndir: cdk\n\n```sh\ncdk deploy --hotswap\n```\n"
  },
  {
    "path": "examples/counter/assets/css/bulma.css",
    "content": "/*! bulma.io v0.9.4 | MIT License | github.com/jgthms/bulma */\n/* Bulma Utilities */\n.button, .input, .textarea, .select select, .file-cta,\n.file-name, .pagination-previous,\n.pagination-next,\n.pagination-link,\n.pagination-ellipsis {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  align-items: center;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  box-shadow: none;\n  display: inline-flex;\n  font-size: 1rem;\n  height: 2.5em;\n  justify-content: flex-start;\n  line-height: 1.5;\n  padding-bottom: calc(0.5em - 1px);\n  padding-left: calc(0.75em - 1px);\n  padding-right: calc(0.75em - 1px);\n  padding-top: calc(0.5em - 1px);\n  position: relative;\n  vertical-align: top;\n}\n\n.button:focus, .input:focus, .textarea:focus, .select select:focus, .file-cta:focus,\n.file-name:focus, .pagination-previous:focus,\n.pagination-next:focus,\n.pagination-link:focus,\n.pagination-ellipsis:focus, .is-focused.button, .is-focused.input, .is-focused.textarea, .select select.is-focused, .is-focused.file-cta,\n.is-focused.file-name, .is-focused.pagination-previous,\n.is-focused.pagination-next,\n.is-focused.pagination-link,\n.is-focused.pagination-ellipsis, .button:active, .input:active, .textarea:active, .select select:active, .file-cta:active,\n.file-name:active, .pagination-previous:active,\n.pagination-next:active,\n.pagination-link:active,\n.pagination-ellipsis:active, .is-active.button, .is-active.input, .is-active.textarea, .select select.is-active, .is-active.file-cta,\n.is-active.file-name, .is-active.pagination-previous,\n.is-active.pagination-next,\n.is-active.pagination-link,\n.is-active.pagination-ellipsis {\n  outline: none;\n}\n\n.button[disabled], .input[disabled], .textarea[disabled], .select select[disabled], .file-cta[disabled],\n.file-name[disabled], .pagination-previous[disabled],\n.pagination-next[disabled],\n.pagination-link[disabled],\n.pagination-ellipsis[disabled],\nfieldset[disabled] .button,\nfieldset[disabled] .input,\nfieldset[disabled] .textarea,\nfieldset[disabled] .select select,\n.select fieldset[disabled] select,\nfieldset[disabled] .file-cta,\nfieldset[disabled] .file-name,\nfieldset[disabled] .pagination-previous,\nfieldset[disabled] .pagination-next,\nfieldset[disabled] .pagination-link,\nfieldset[disabled] .pagination-ellipsis {\n  cursor: not-allowed;\n}\n\n.button, .file, .breadcrumb, .pagination-previous,\n.pagination-next,\n.pagination-link,\n.pagination-ellipsis, .tabs, .is-unselectable {\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n\n.select:not(.is-multiple):not(.is-loading)::after, .navbar-link:not(.is-arrowless)::after {\n  border: 3px solid transparent;\n  border-radius: 2px;\n  border-right: 0;\n  border-top: 0;\n  content: \" \";\n  display: block;\n  height: 0.625em;\n  margin-top: -0.4375em;\n  pointer-events: none;\n  position: absolute;\n  top: 50%;\n  transform: rotate(-45deg);\n  transform-origin: center;\n  width: 0.625em;\n}\n\n.box:not(:last-child), .content:not(:last-child), .notification:not(:last-child), .progress:not(:last-child), .table:not(:last-child), .table-container:not(:last-child), .title:not(:last-child),\n.subtitle:not(:last-child), .block:not(:last-child), .breadcrumb:not(:last-child), .level:not(:last-child), .message:not(:last-child), .pagination:not(:last-child), .tabs:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.delete, .modal-close {\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  background-color: rgba(10, 10, 10, 0.2);\n  border: none;\n  border-radius: 9999px;\n  cursor: pointer;\n  pointer-events: auto;\n  display: inline-block;\n  flex-grow: 0;\n  flex-shrink: 0;\n  font-size: 0;\n  height: 20px;\n  max-height: 20px;\n  max-width: 20px;\n  min-height: 20px;\n  min-width: 20px;\n  outline: none;\n  position: relative;\n  vertical-align: top;\n  width: 20px;\n}\n\n.delete::before, .modal-close::before, .delete::after, .modal-close::after {\n  background-color: white;\n  content: \"\";\n  display: block;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translateX(-50%) translateY(-50%) rotate(45deg);\n  transform-origin: center center;\n}\n\n.delete::before, .modal-close::before {\n  height: 2px;\n  width: 50%;\n}\n\n.delete::after, .modal-close::after {\n  height: 50%;\n  width: 2px;\n}\n\n.delete:hover, .modal-close:hover, .delete:focus, .modal-close:focus {\n  background-color: rgba(10, 10, 10, 0.3);\n}\n\n.delete:active, .modal-close:active {\n  background-color: rgba(10, 10, 10, 0.4);\n}\n\n.is-small.delete, .is-small.modal-close {\n  height: 16px;\n  max-height: 16px;\n  max-width: 16px;\n  min-height: 16px;\n  min-width: 16px;\n  width: 16px;\n}\n\n.is-medium.delete, .is-medium.modal-close {\n  height: 24px;\n  max-height: 24px;\n  max-width: 24px;\n  min-height: 24px;\n  min-width: 24px;\n  width: 24px;\n}\n\n.is-large.delete, .is-large.modal-close {\n  height: 32px;\n  max-height: 32px;\n  max-width: 32px;\n  min-height: 32px;\n  min-width: 32px;\n  width: 32px;\n}\n\n.button.is-loading::after, .loader, .select.is-loading::after, .control.is-loading::after {\n  -webkit-animation: spinAround 500ms infinite linear;\n          animation: spinAround 500ms infinite linear;\n  border: 2px solid #dbdbdb;\n  border-radius: 9999px;\n  border-right-color: transparent;\n  border-top-color: transparent;\n  content: \"\";\n  display: block;\n  height: 1em;\n  position: relative;\n  width: 1em;\n}\n\n.image.is-square img,\n.image.is-square .has-ratio, .image.is-1by1 img,\n.image.is-1by1 .has-ratio, .image.is-5by4 img,\n.image.is-5by4 .has-ratio, .image.is-4by3 img,\n.image.is-4by3 .has-ratio, .image.is-3by2 img,\n.image.is-3by2 .has-ratio, .image.is-5by3 img,\n.image.is-5by3 .has-ratio, .image.is-16by9 img,\n.image.is-16by9 .has-ratio, .image.is-2by1 img,\n.image.is-2by1 .has-ratio, .image.is-3by1 img,\n.image.is-3by1 .has-ratio, .image.is-4by5 img,\n.image.is-4by5 .has-ratio, .image.is-3by4 img,\n.image.is-3by4 .has-ratio, .image.is-2by3 img,\n.image.is-2by3 .has-ratio, .image.is-3by5 img,\n.image.is-3by5 .has-ratio, .image.is-9by16 img,\n.image.is-9by16 .has-ratio, .image.is-1by2 img,\n.image.is-1by2 .has-ratio, .image.is-1by3 img,\n.image.is-1by3 .has-ratio, .modal, .modal-background, .is-overlay, .hero-video {\n  bottom: 0;\n  left: 0;\n  position: absolute;\n  right: 0;\n  top: 0;\n}\n\n.navbar-burger {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n  background: none;\n  border: none;\n  color: currentColor;\n  font-family: inherit;\n  font-size: 1em;\n  margin: 0;\n  padding: 0;\n}\n\n/* Bulma Base */\n/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */\nhtml,\nbody,\np,\nol,\nul,\nli,\ndl,\ndt,\ndd,\nblockquote,\nfigure,\nfieldset,\nlegend,\ntextarea,\npre,\niframe,\nhr,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  margin: 0;\n  padding: 0;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  font-size: 100%;\n  font-weight: normal;\n}\n\nul {\n  list-style: none;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n}\n\nhtml {\n  box-sizing: border-box;\n}\n\n*, *::before, *::after {\n  box-sizing: inherit;\n}\n\nimg,\nvideo {\n  height: auto;\n  max-width: 100%;\n}\n\niframe {\n  border: 0;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n\ntd:not([align]),\nth:not([align]) {\n  text-align: inherit;\n}\n\nhtml {\n  background-color: white;\n  font-size: 16px;\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  min-width: 300px;\n  overflow-x: hidden;\n  overflow-y: scroll;\n  text-rendering: optimizeLegibility;\n  -webkit-text-size-adjust: 100%;\n     -moz-text-size-adjust: 100%;\n          text-size-adjust: 100%;\n}\n\narticle,\naside,\nfigure,\nfooter,\nheader,\nhgroup,\nsection {\n  display: block;\n}\n\nbody,\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif;\n}\n\ncode,\npre {\n  -moz-osx-font-smoothing: auto;\n  -webkit-font-smoothing: auto;\n  font-family: monospace;\n}\n\nbody {\n  color: #4a4a4a;\n  font-size: 1em;\n  font-weight: 400;\n  line-height: 1.5;\n}\n\na {\n  color: #485fc7;\n  cursor: pointer;\n  text-decoration: none;\n}\n\na strong {\n  color: currentColor;\n}\n\na:hover {\n  color: #363636;\n}\n\ncode {\n  background-color: whitesmoke;\n  color: #da1039;\n  font-size: 0.875em;\n  font-weight: normal;\n  padding: 0.25em 0.5em 0.25em;\n}\n\nhr {\n  background-color: whitesmoke;\n  border: none;\n  display: block;\n  height: 2px;\n  margin: 1.5rem 0;\n}\n\nimg {\n  height: auto;\n  max-width: 100%;\n}\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  vertical-align: baseline;\n}\n\nsmall {\n  font-size: 0.875em;\n}\n\nspan {\n  font-style: inherit;\n  font-weight: inherit;\n}\n\nstrong {\n  color: #363636;\n  font-weight: 700;\n}\n\nfieldset {\n  border: none;\n}\n\npre {\n  -webkit-overflow-scrolling: touch;\n  background-color: whitesmoke;\n  color: #4a4a4a;\n  font-size: 0.875em;\n  overflow-x: auto;\n  padding: 1.25rem 1.5rem;\n  white-space: pre;\n  word-wrap: normal;\n}\n\npre code {\n  background-color: transparent;\n  color: currentColor;\n  font-size: 1em;\n  padding: 0;\n}\n\ntable td,\ntable th {\n  vertical-align: top;\n}\n\ntable td:not([align]),\ntable th:not([align]) {\n  text-align: inherit;\n}\n\ntable th {\n  color: #363636;\n}\n\n@-webkit-keyframes spinAround {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(359deg);\n  }\n}\n\n@keyframes spinAround {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(359deg);\n  }\n}\n\n/* Bulma Elements */\n.box {\n  background-color: white;\n  border-radius: 6px;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  color: #4a4a4a;\n  display: block;\n  padding: 1.25rem;\n}\n\na.box:hover, a.box:focus {\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0 0 1px #485fc7;\n}\n\na.box:active {\n  box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2), 0 0 0 1px #485fc7;\n}\n\n.button {\n  background-color: white;\n  border-color: #dbdbdb;\n  border-width: 1px;\n  color: #363636;\n  cursor: pointer;\n  justify-content: center;\n  padding-bottom: calc(0.5em - 1px);\n  padding-left: 1em;\n  padding-right: 1em;\n  padding-top: calc(0.5em - 1px);\n  text-align: center;\n  white-space: nowrap;\n}\n\n.button strong {\n  color: inherit;\n}\n\n.button .icon, .button .icon.is-small, .button .icon.is-medium, .button .icon.is-large {\n  height: 1.5em;\n  width: 1.5em;\n}\n\n.button .icon:first-child:not(:last-child) {\n  margin-left: calc(-0.5em - 1px);\n  margin-right: 0.25em;\n}\n\n.button .icon:last-child:not(:first-child) {\n  margin-left: 0.25em;\n  margin-right: calc(-0.5em - 1px);\n}\n\n.button .icon:first-child:last-child {\n  margin-left: calc(-0.5em - 1px);\n  margin-right: calc(-0.5em - 1px);\n}\n\n.button:hover, .button.is-hovered {\n  border-color: #b5b5b5;\n  color: #363636;\n}\n\n.button:focus, .button.is-focused {\n  border-color: #485fc7;\n  color: #363636;\n}\n\n.button:focus:not(:active), .button.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.button:active, .button.is-active {\n  border-color: #4a4a4a;\n  color: #363636;\n}\n\n.button.is-text {\n  background-color: transparent;\n  border-color: transparent;\n  color: #4a4a4a;\n  text-decoration: underline;\n}\n\n.button.is-text:hover, .button.is-text.is-hovered, .button.is-text:focus, .button.is-text.is-focused {\n  background-color: whitesmoke;\n  color: #363636;\n}\n\n.button.is-text:active, .button.is-text.is-active {\n  background-color: #e8e8e8;\n  color: #363636;\n}\n\n.button.is-text[disabled],\nfieldset[disabled] .button.is-text {\n  background-color: transparent;\n  border-color: transparent;\n  box-shadow: none;\n}\n\n.button.is-ghost {\n  background: none;\n  border-color: transparent;\n  color: #485fc7;\n  text-decoration: none;\n}\n\n.button.is-ghost:hover, .button.is-ghost.is-hovered {\n  color: #485fc7;\n  text-decoration: underline;\n}\n\n.button.is-white {\n  background-color: white;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white:hover, .button.is-white.is-hovered {\n  background-color: #f9f9f9;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white:focus, .button.is-white.is-focused {\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white:focus:not(:active), .button.is-white.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25);\n}\n\n.button.is-white:active, .button.is-white.is-active {\n  background-color: #f2f2f2;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white[disabled],\nfieldset[disabled] .button.is-white {\n  background-color: white;\n  border-color: white;\n  box-shadow: none;\n}\n\n.button.is-white.is-inverted {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.button.is-white.is-inverted:hover, .button.is-white.is-inverted.is-hovered {\n  background-color: black;\n}\n\n.button.is-white.is-inverted[disabled],\nfieldset[disabled] .button.is-white.is-inverted {\n  background-color: #0a0a0a;\n  border-color: transparent;\n  box-shadow: none;\n  color: white;\n}\n\n.button.is-white.is-loading::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-white.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  color: white;\n}\n\n.button.is-white.is-outlined:hover, .button.is-white.is-outlined.is-hovered, .button.is-white.is-outlined:focus, .button.is-white.is-outlined.is-focused {\n  background-color: white;\n  border-color: white;\n  color: #0a0a0a;\n}\n\n.button.is-white.is-outlined.is-loading::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-white.is-outlined.is-loading:hover::after, .button.is-white.is-outlined.is-loading.is-hovered::after, .button.is-white.is-outlined.is-loading:focus::after, .button.is-white.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-white.is-outlined[disabled],\nfieldset[disabled] .button.is-white.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  box-shadow: none;\n  color: white;\n}\n\n.button.is-white.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  color: #0a0a0a;\n}\n\n.button.is-white.is-inverted.is-outlined:hover, .button.is-white.is-inverted.is-outlined.is-hovered, .button.is-white.is-inverted.is-outlined:focus, .button.is-white.is-inverted.is-outlined.is-focused {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.button.is-white.is-inverted.is-outlined.is-loading:hover::after, .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-white.is-inverted.is-outlined.is-loading:focus::after, .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-white.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-white.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  box-shadow: none;\n  color: #0a0a0a;\n}\n\n.button.is-black {\n  background-color: #0a0a0a;\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black:hover, .button.is-black.is-hovered {\n  background-color: #040404;\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black:focus, .button.is-black.is-focused {\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black:focus:not(:active), .button.is-black.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25);\n}\n\n.button.is-black:active, .button.is-black.is-active {\n  background-color: black;\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black[disabled],\nfieldset[disabled] .button.is-black {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  box-shadow: none;\n}\n\n.button.is-black.is-inverted {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-inverted:hover, .button.is-black.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-black.is-inverted[disabled],\nfieldset[disabled] .button.is-black.is-inverted {\n  background-color: white;\n  border-color: transparent;\n  box-shadow: none;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-loading::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-black.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-outlined:hover, .button.is-black.is-outlined.is-hovered, .button.is-black.is-outlined:focus, .button.is-black.is-outlined.is-focused {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  color: white;\n}\n\n.button.is-black.is-outlined.is-loading::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-black.is-outlined.is-loading:hover::after, .button.is-black.is-outlined.is-loading.is-hovered::after, .button.is-black.is-outlined.is-loading:focus::after, .button.is-black.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-black.is-outlined[disabled],\nfieldset[disabled] .button.is-black.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  box-shadow: none;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  color: white;\n}\n\n.button.is-black.is-inverted.is-outlined:hover, .button.is-black.is-inverted.is-outlined.is-hovered, .button.is-black.is-inverted.is-outlined:focus, .button.is-black.is-inverted.is-outlined.is-focused {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-inverted.is-outlined.is-loading:hover::after, .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-black.is-inverted.is-outlined.is-loading:focus::after, .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-black.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-black.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  box-shadow: none;\n  color: white;\n}\n\n.button.is-light {\n  background-color: whitesmoke;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light:hover, .button.is-light.is-hovered {\n  background-color: #eeeeee;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light:focus, .button.is-light.is-focused {\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light:focus:not(:active), .button.is-light.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25);\n}\n\n.button.is-light:active, .button.is-light.is-active {\n  background-color: #e8e8e8;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light[disabled],\nfieldset[disabled] .button.is-light {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  box-shadow: none;\n}\n\n.button.is-light.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: whitesmoke;\n}\n\n.button.is-light.is-inverted:hover, .button.is-light.is-inverted.is-hovered {\n  background-color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light.is-inverted[disabled],\nfieldset[disabled] .button.is-light.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: transparent;\n  box-shadow: none;\n  color: whitesmoke;\n}\n\n.button.is-light.is-loading::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-light.is-outlined {\n  background-color: transparent;\n  border-color: whitesmoke;\n  color: whitesmoke;\n}\n\n.button.is-light.is-outlined:hover, .button.is-light.is-outlined.is-hovered, .button.is-light.is-outlined:focus, .button.is-light.is-outlined.is-focused {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light.is-outlined.is-loading::after {\n  border-color: transparent transparent whitesmoke whitesmoke !important;\n}\n\n.button.is-light.is-outlined.is-loading:hover::after, .button.is-light.is-outlined.is-loading.is-hovered::after, .button.is-light.is-outlined.is-loading:focus::after, .button.is-light.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-light.is-outlined[disabled],\nfieldset[disabled] .button.is-light.is-outlined {\n  background-color: transparent;\n  border-color: whitesmoke;\n  box-shadow: none;\n  color: whitesmoke;\n}\n\n.button.is-light.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light.is-inverted.is-outlined:hover, .button.is-light.is-inverted.is-outlined.is-hovered, .button.is-light.is-inverted.is-outlined:focus, .button.is-light.is-inverted.is-outlined.is-focused {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: whitesmoke;\n}\n\n.button.is-light.is-inverted.is-outlined.is-loading:hover::after, .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-light.is-inverted.is-outlined.is-loading:focus::after, .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent whitesmoke whitesmoke !important;\n}\n\n.button.is-light.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-light.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  box-shadow: none;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-dark {\n  background-color: #363636;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark:hover, .button.is-dark.is-hovered {\n  background-color: #2f2f2f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark:focus, .button.is-dark.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark:focus:not(:active), .button.is-dark.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25);\n}\n\n.button.is-dark:active, .button.is-dark.is-active {\n  background-color: #292929;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark[disabled],\nfieldset[disabled] .button.is-dark {\n  background-color: #363636;\n  border-color: #363636;\n  box-shadow: none;\n}\n\n.button.is-dark.is-inverted {\n  background-color: #fff;\n  color: #363636;\n}\n\n.button.is-dark.is-inverted:hover, .button.is-dark.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-dark.is-inverted[disabled],\nfieldset[disabled] .button.is-dark.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #363636;\n}\n\n.button.is-dark.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-dark.is-outlined {\n  background-color: transparent;\n  border-color: #363636;\n  color: #363636;\n}\n\n.button.is-dark.is-outlined:hover, .button.is-dark.is-outlined.is-hovered, .button.is-dark.is-outlined:focus, .button.is-dark.is-outlined.is-focused {\n  background-color: #363636;\n  border-color: #363636;\n  color: #fff;\n}\n\n.button.is-dark.is-outlined.is-loading::after {\n  border-color: transparent transparent #363636 #363636 !important;\n}\n\n.button.is-dark.is-outlined.is-loading:hover::after, .button.is-dark.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-outlined.is-loading:focus::after, .button.is-dark.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-dark.is-outlined[disabled],\nfieldset[disabled] .button.is-dark.is-outlined {\n  background-color: transparent;\n  border-color: #363636;\n  box-shadow: none;\n  color: #363636;\n}\n\n.button.is-dark.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-dark.is-inverted.is-outlined:hover, .button.is-dark.is-inverted.is-outlined.is-hovered, .button.is-dark.is-inverted.is-outlined:focus, .button.is-dark.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #363636;\n}\n\n.button.is-dark.is-inverted.is-outlined.is-loading:hover::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-inverted.is-outlined.is-loading:focus::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #363636 #363636 !important;\n}\n\n.button.is-dark.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-dark.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-primary {\n  background-color: #00d1b2;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary:hover, .button.is-primary.is-hovered {\n  background-color: #00c4a7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary:focus, .button.is-primary.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary:focus:not(:active), .button.is-primary.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25);\n}\n\n.button.is-primary:active, .button.is-primary.is-active {\n  background-color: #00b89c;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary[disabled],\nfieldset[disabled] .button.is-primary {\n  background-color: #00d1b2;\n  border-color: #00d1b2;\n  box-shadow: none;\n}\n\n.button.is-primary.is-inverted {\n  background-color: #fff;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-inverted:hover, .button.is-primary.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-primary.is-inverted[disabled],\nfieldset[disabled] .button.is-primary.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-primary.is-outlined {\n  background-color: transparent;\n  border-color: #00d1b2;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-outlined:hover, .button.is-primary.is-outlined.is-hovered, .button.is-primary.is-outlined:focus, .button.is-primary.is-outlined.is-focused {\n  background-color: #00d1b2;\n  border-color: #00d1b2;\n  color: #fff;\n}\n\n.button.is-primary.is-outlined.is-loading::after {\n  border-color: transparent transparent #00d1b2 #00d1b2 !important;\n}\n\n.button.is-primary.is-outlined.is-loading:hover::after, .button.is-primary.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-outlined.is-loading:focus::after, .button.is-primary.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-primary.is-outlined[disabled],\nfieldset[disabled] .button.is-primary.is-outlined {\n  background-color: transparent;\n  border-color: #00d1b2;\n  box-shadow: none;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-primary.is-inverted.is-outlined:hover, .button.is-primary.is-inverted.is-outlined.is-hovered, .button.is-primary.is-inverted.is-outlined:focus, .button.is-primary.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-inverted.is-outlined.is-loading:hover::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-inverted.is-outlined.is-loading:focus::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #00d1b2 #00d1b2 !important;\n}\n\n.button.is-primary.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-primary.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-primary.is-light {\n  background-color: #ebfffc;\n  color: #00947e;\n}\n\n.button.is-primary.is-light:hover, .button.is-primary.is-light.is-hovered {\n  background-color: #defffa;\n  border-color: transparent;\n  color: #00947e;\n}\n\n.button.is-primary.is-light:active, .button.is-primary.is-light.is-active {\n  background-color: #d1fff8;\n  border-color: transparent;\n  color: #00947e;\n}\n\n.button.is-link {\n  background-color: #485fc7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link:hover, .button.is-link.is-hovered {\n  background-color: #3e56c4;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link:focus, .button.is-link.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link:focus:not(:active), .button.is-link.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.button.is-link:active, .button.is-link.is-active {\n  background-color: #3a51bb;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link[disabled],\nfieldset[disabled] .button.is-link {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  box-shadow: none;\n}\n\n.button.is-link.is-inverted {\n  background-color: #fff;\n  color: #485fc7;\n}\n\n.button.is-link.is-inverted:hover, .button.is-link.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-link.is-inverted[disabled],\nfieldset[disabled] .button.is-link.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #485fc7;\n}\n\n.button.is-link.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-link.is-outlined {\n  background-color: transparent;\n  border-color: #485fc7;\n  color: #485fc7;\n}\n\n.button.is-link.is-outlined:hover, .button.is-link.is-outlined.is-hovered, .button.is-link.is-outlined:focus, .button.is-link.is-outlined.is-focused {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n}\n\n.button.is-link.is-outlined.is-loading::after {\n  border-color: transparent transparent #485fc7 #485fc7 !important;\n}\n\n.button.is-link.is-outlined.is-loading:hover::after, .button.is-link.is-outlined.is-loading.is-hovered::after, .button.is-link.is-outlined.is-loading:focus::after, .button.is-link.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-link.is-outlined[disabled],\nfieldset[disabled] .button.is-link.is-outlined {\n  background-color: transparent;\n  border-color: #485fc7;\n  box-shadow: none;\n  color: #485fc7;\n}\n\n.button.is-link.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-link.is-inverted.is-outlined:hover, .button.is-link.is-inverted.is-outlined.is-hovered, .button.is-link.is-inverted.is-outlined:focus, .button.is-link.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #485fc7;\n}\n\n.button.is-link.is-inverted.is-outlined.is-loading:hover::after, .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-link.is-inverted.is-outlined.is-loading:focus::after, .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #485fc7 #485fc7 !important;\n}\n\n.button.is-link.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-link.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-link.is-light {\n  background-color: #eff1fa;\n  color: #3850b7;\n}\n\n.button.is-link.is-light:hover, .button.is-link.is-light.is-hovered {\n  background-color: #e6e9f7;\n  border-color: transparent;\n  color: #3850b7;\n}\n\n.button.is-link.is-light:active, .button.is-link.is-light.is-active {\n  background-color: #dce0f4;\n  border-color: transparent;\n  color: #3850b7;\n}\n\n.button.is-info {\n  background-color: #3e8ed0;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info:hover, .button.is-info.is-hovered {\n  background-color: #3488ce;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info:focus, .button.is-info.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info:focus:not(:active), .button.is-info.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(62, 142, 208, 0.25);\n}\n\n.button.is-info:active, .button.is-info.is-active {\n  background-color: #3082c5;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info[disabled],\nfieldset[disabled] .button.is-info {\n  background-color: #3e8ed0;\n  border-color: #3e8ed0;\n  box-shadow: none;\n}\n\n.button.is-info.is-inverted {\n  background-color: #fff;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-inverted:hover, .button.is-info.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-info.is-inverted[disabled],\nfieldset[disabled] .button.is-info.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-info.is-outlined {\n  background-color: transparent;\n  border-color: #3e8ed0;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-outlined:hover, .button.is-info.is-outlined.is-hovered, .button.is-info.is-outlined:focus, .button.is-info.is-outlined.is-focused {\n  background-color: #3e8ed0;\n  border-color: #3e8ed0;\n  color: #fff;\n}\n\n.button.is-info.is-outlined.is-loading::after {\n  border-color: transparent transparent #3e8ed0 #3e8ed0 !important;\n}\n\n.button.is-info.is-outlined.is-loading:hover::after, .button.is-info.is-outlined.is-loading.is-hovered::after, .button.is-info.is-outlined.is-loading:focus::after, .button.is-info.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-info.is-outlined[disabled],\nfieldset[disabled] .button.is-info.is-outlined {\n  background-color: transparent;\n  border-color: #3e8ed0;\n  box-shadow: none;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-info.is-inverted.is-outlined:hover, .button.is-info.is-inverted.is-outlined.is-hovered, .button.is-info.is-inverted.is-outlined:focus, .button.is-info.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-inverted.is-outlined.is-loading:hover::after, .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-info.is-inverted.is-outlined.is-loading:focus::after, .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #3e8ed0 #3e8ed0 !important;\n}\n\n.button.is-info.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-info.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-info.is-light {\n  background-color: #eff5fb;\n  color: #296fa8;\n}\n\n.button.is-info.is-light:hover, .button.is-info.is-light.is-hovered {\n  background-color: #e4eff9;\n  border-color: transparent;\n  color: #296fa8;\n}\n\n.button.is-info.is-light:active, .button.is-info.is-light.is-active {\n  background-color: #dae9f6;\n  border-color: transparent;\n  color: #296fa8;\n}\n\n.button.is-success {\n  background-color: #48c78e;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success:hover, .button.is-success.is-hovered {\n  background-color: #3ec487;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success:focus, .button.is-success.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success:focus:not(:active), .button.is-success.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(72, 199, 142, 0.25);\n}\n\n.button.is-success:active, .button.is-success.is-active {\n  background-color: #3abb81;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success[disabled],\nfieldset[disabled] .button.is-success {\n  background-color: #48c78e;\n  border-color: #48c78e;\n  box-shadow: none;\n}\n\n.button.is-success.is-inverted {\n  background-color: #fff;\n  color: #48c78e;\n}\n\n.button.is-success.is-inverted:hover, .button.is-success.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-success.is-inverted[disabled],\nfieldset[disabled] .button.is-success.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #48c78e;\n}\n\n.button.is-success.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-success.is-outlined {\n  background-color: transparent;\n  border-color: #48c78e;\n  color: #48c78e;\n}\n\n.button.is-success.is-outlined:hover, .button.is-success.is-outlined.is-hovered, .button.is-success.is-outlined:focus, .button.is-success.is-outlined.is-focused {\n  background-color: #48c78e;\n  border-color: #48c78e;\n  color: #fff;\n}\n\n.button.is-success.is-outlined.is-loading::after {\n  border-color: transparent transparent #48c78e #48c78e !important;\n}\n\n.button.is-success.is-outlined.is-loading:hover::after, .button.is-success.is-outlined.is-loading.is-hovered::after, .button.is-success.is-outlined.is-loading:focus::after, .button.is-success.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-success.is-outlined[disabled],\nfieldset[disabled] .button.is-success.is-outlined {\n  background-color: transparent;\n  border-color: #48c78e;\n  box-shadow: none;\n  color: #48c78e;\n}\n\n.button.is-success.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-success.is-inverted.is-outlined:hover, .button.is-success.is-inverted.is-outlined.is-hovered, .button.is-success.is-inverted.is-outlined:focus, .button.is-success.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #48c78e;\n}\n\n.button.is-success.is-inverted.is-outlined.is-loading:hover::after, .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-success.is-inverted.is-outlined.is-loading:focus::after, .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #48c78e #48c78e !important;\n}\n\n.button.is-success.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-success.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-success.is-light {\n  background-color: #effaf5;\n  color: #257953;\n}\n\n.button.is-success.is-light:hover, .button.is-success.is-light.is-hovered {\n  background-color: #e6f7ef;\n  border-color: transparent;\n  color: #257953;\n}\n\n.button.is-success.is-light:active, .button.is-success.is-light.is-active {\n  background-color: #dcf4e9;\n  border-color: transparent;\n  color: #257953;\n}\n\n.button.is-warning {\n  background-color: #ffe08a;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning:hover, .button.is-warning.is-hovered {\n  background-color: #ffdc7d;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning:focus, .button.is-warning.is-focused {\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning:focus:not(:active), .button.is-warning.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(255, 224, 138, 0.25);\n}\n\n.button.is-warning:active, .button.is-warning.is-active {\n  background-color: #ffd970;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning[disabled],\nfieldset[disabled] .button.is-warning {\n  background-color: #ffe08a;\n  border-color: #ffe08a;\n  box-shadow: none;\n}\n\n.button.is-warning.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: #ffe08a;\n}\n\n.button.is-warning.is-inverted:hover, .button.is-warning.is-inverted.is-hovered {\n  background-color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-inverted[disabled],\nfieldset[disabled] .button.is-warning.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: transparent;\n  box-shadow: none;\n  color: #ffe08a;\n}\n\n.button.is-warning.is-loading::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-warning.is-outlined {\n  background-color: transparent;\n  border-color: #ffe08a;\n  color: #ffe08a;\n}\n\n.button.is-warning.is-outlined:hover, .button.is-warning.is-outlined.is-hovered, .button.is-warning.is-outlined:focus, .button.is-warning.is-outlined.is-focused {\n  background-color: #ffe08a;\n  border-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-outlined.is-loading::after {\n  border-color: transparent transparent #ffe08a #ffe08a !important;\n}\n\n.button.is-warning.is-outlined.is-loading:hover::after, .button.is-warning.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-outlined.is-loading:focus::after, .button.is-warning.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-warning.is-outlined[disabled],\nfieldset[disabled] .button.is-warning.is-outlined {\n  background-color: transparent;\n  border-color: #ffe08a;\n  box-shadow: none;\n  color: #ffe08a;\n}\n\n.button.is-warning.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-inverted.is-outlined:hover, .button.is-warning.is-inverted.is-outlined.is-hovered, .button.is-warning.is-inverted.is-outlined:focus, .button.is-warning.is-inverted.is-outlined.is-focused {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: #ffe08a;\n}\n\n.button.is-warning.is-inverted.is-outlined.is-loading:hover::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-inverted.is-outlined.is-loading:focus::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #ffe08a #ffe08a !important;\n}\n\n.button.is-warning.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-warning.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  box-shadow: none;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-light {\n  background-color: #fffaeb;\n  color: #946c00;\n}\n\n.button.is-warning.is-light:hover, .button.is-warning.is-light.is-hovered {\n  background-color: #fff6de;\n  border-color: transparent;\n  color: #946c00;\n}\n\n.button.is-warning.is-light:active, .button.is-warning.is-light.is-active {\n  background-color: #fff3d1;\n  border-color: transparent;\n  color: #946c00;\n}\n\n.button.is-danger {\n  background-color: #f14668;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger:hover, .button.is-danger.is-hovered {\n  background-color: #f03a5f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger:focus, .button.is-danger.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger:focus:not(:active), .button.is-danger.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25);\n}\n\n.button.is-danger:active, .button.is-danger.is-active {\n  background-color: #ef2e55;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger[disabled],\nfieldset[disabled] .button.is-danger {\n  background-color: #f14668;\n  border-color: #f14668;\n  box-shadow: none;\n}\n\n.button.is-danger.is-inverted {\n  background-color: #fff;\n  color: #f14668;\n}\n\n.button.is-danger.is-inverted:hover, .button.is-danger.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-danger.is-inverted[disabled],\nfieldset[disabled] .button.is-danger.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #f14668;\n}\n\n.button.is-danger.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-danger.is-outlined {\n  background-color: transparent;\n  border-color: #f14668;\n  color: #f14668;\n}\n\n.button.is-danger.is-outlined:hover, .button.is-danger.is-outlined.is-hovered, .button.is-danger.is-outlined:focus, .button.is-danger.is-outlined.is-focused {\n  background-color: #f14668;\n  border-color: #f14668;\n  color: #fff;\n}\n\n.button.is-danger.is-outlined.is-loading::after {\n  border-color: transparent transparent #f14668 #f14668 !important;\n}\n\n.button.is-danger.is-outlined.is-loading:hover::after, .button.is-danger.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-outlined.is-loading:focus::after, .button.is-danger.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-danger.is-outlined[disabled],\nfieldset[disabled] .button.is-danger.is-outlined {\n  background-color: transparent;\n  border-color: #f14668;\n  box-shadow: none;\n  color: #f14668;\n}\n\n.button.is-danger.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-danger.is-inverted.is-outlined:hover, .button.is-danger.is-inverted.is-outlined.is-hovered, .button.is-danger.is-inverted.is-outlined:focus, .button.is-danger.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #f14668;\n}\n\n.button.is-danger.is-inverted.is-outlined.is-loading:hover::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-inverted.is-outlined.is-loading:focus::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #f14668 #f14668 !important;\n}\n\n.button.is-danger.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-danger.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-danger.is-light {\n  background-color: #feecf0;\n  color: #cc0f35;\n}\n\n.button.is-danger.is-light:hover, .button.is-danger.is-light.is-hovered {\n  background-color: #fde0e6;\n  border-color: transparent;\n  color: #cc0f35;\n}\n\n.button.is-danger.is-light:active, .button.is-danger.is-light.is-active {\n  background-color: #fcd4dc;\n  border-color: transparent;\n  color: #cc0f35;\n}\n\n.button.is-small {\n  font-size: 0.75rem;\n}\n\n.button.is-small:not(.is-rounded) {\n  border-radius: 2px;\n}\n\n.button.is-normal {\n  font-size: 1rem;\n}\n\n.button.is-medium {\n  font-size: 1.25rem;\n}\n\n.button.is-large {\n  font-size: 1.5rem;\n}\n\n.button[disabled],\nfieldset[disabled] .button {\n  background-color: white;\n  border-color: #dbdbdb;\n  box-shadow: none;\n  opacity: 0.5;\n}\n\n.button.is-fullwidth {\n  display: flex;\n  width: 100%;\n}\n\n.button.is-loading {\n  color: transparent !important;\n  pointer-events: none;\n}\n\n.button.is-loading::after {\n  position: absolute;\n  left: calc(50% - (1em * 0.5));\n  top: calc(50% - (1em * 0.5));\n  position: absolute !important;\n}\n\n.button.is-static {\n  background-color: whitesmoke;\n  border-color: #dbdbdb;\n  color: #7a7a7a;\n  box-shadow: none;\n  pointer-events: none;\n}\n\n.button.is-rounded {\n  border-radius: 9999px;\n  padding-left: calc(1em + 0.25em);\n  padding-right: calc(1em + 0.25em);\n}\n\n.buttons {\n  align-items: center;\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n\n.buttons .button {\n  margin-bottom: 0.5rem;\n}\n\n.buttons .button:not(:last-child):not(.is-fullwidth) {\n  margin-right: 0.5rem;\n}\n\n.buttons:last-child {\n  margin-bottom: -0.5rem;\n}\n\n.buttons:not(:last-child) {\n  margin-bottom: 1rem;\n}\n\n.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large) {\n  font-size: 0.75rem;\n}\n\n.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded) {\n  border-radius: 2px;\n}\n\n.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large) {\n  font-size: 1.25rem;\n}\n\n.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium) {\n  font-size: 1.5rem;\n}\n\n.buttons.has-addons .button:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.buttons.has-addons .button:not(:last-child) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n  margin-right: -1px;\n}\n\n.buttons.has-addons .button:last-child {\n  margin-right: 0;\n}\n\n.buttons.has-addons .button:hover, .buttons.has-addons .button.is-hovered {\n  z-index: 2;\n}\n\n.buttons.has-addons .button:focus, .buttons.has-addons .button.is-focused, .buttons.has-addons .button:active, .buttons.has-addons .button.is-active, .buttons.has-addons .button.is-selected {\n  z-index: 3;\n}\n\n.buttons.has-addons .button:focus:hover, .buttons.has-addons .button.is-focused:hover, .buttons.has-addons .button:active:hover, .buttons.has-addons .button.is-active:hover, .buttons.has-addons .button.is-selected:hover {\n  z-index: 4;\n}\n\n.buttons.has-addons .button.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.buttons.is-centered {\n  justify-content: center;\n}\n\n.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth) {\n  margin-left: 0.25rem;\n  margin-right: 0.25rem;\n}\n\n.buttons.is-right {\n  justify-content: flex-end;\n}\n\n.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth) {\n  margin-left: 0.25rem;\n  margin-right: 0.25rem;\n}\n\n@media screen and (max-width: 768px) {\n  .button.is-responsive.is-small {\n    font-size: 0.5625rem;\n  }\n  .button.is-responsive,\n  .button.is-responsive.is-normal {\n    font-size: 0.65625rem;\n  }\n  .button.is-responsive.is-medium {\n    font-size: 0.75rem;\n  }\n  .button.is-responsive.is-large {\n    font-size: 1rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .button.is-responsive.is-small {\n    font-size: 0.65625rem;\n  }\n  .button.is-responsive,\n  .button.is-responsive.is-normal {\n    font-size: 0.75rem;\n  }\n  .button.is-responsive.is-medium {\n    font-size: 1rem;\n  }\n  .button.is-responsive.is-large {\n    font-size: 1.25rem;\n  }\n}\n\n.container {\n  flex-grow: 1;\n  margin: 0 auto;\n  position: relative;\n  width: auto;\n}\n\n.container.is-fluid {\n  max-width: none !important;\n  padding-left: 32px;\n  padding-right: 32px;\n  width: 100%;\n}\n\n@media screen and (min-width: 1024px) {\n  .container {\n    max-width: 960px;\n  }\n}\n\n@media screen and (max-width: 1215px) {\n  .container.is-widescreen:not(.is-max-desktop) {\n    max-width: 1152px;\n  }\n}\n\n@media screen and (max-width: 1407px) {\n  .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen) {\n    max-width: 1344px;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .container:not(.is-max-desktop) {\n    max-width: 1152px;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .container:not(.is-max-desktop):not(.is-max-widescreen) {\n    max-width: 1344px;\n  }\n}\n\n.content li + li {\n  margin-top: 0.25em;\n}\n\n.content p:not(:last-child),\n.content dl:not(:last-child),\n.content ol:not(:last-child),\n.content ul:not(:last-child),\n.content blockquote:not(:last-child),\n.content pre:not(:last-child),\n.content table:not(:last-child) {\n  margin-bottom: 1em;\n}\n\n.content h1,\n.content h2,\n.content h3,\n.content h4,\n.content h5,\n.content h6 {\n  color: #363636;\n  font-weight: 600;\n  line-height: 1.125;\n}\n\n.content h1 {\n  font-size: 2em;\n  margin-bottom: 0.5em;\n}\n\n.content h1:not(:first-child) {\n  margin-top: 1em;\n}\n\n.content h2 {\n  font-size: 1.75em;\n  margin-bottom: 0.5714em;\n}\n\n.content h2:not(:first-child) {\n  margin-top: 1.1428em;\n}\n\n.content h3 {\n  font-size: 1.5em;\n  margin-bottom: 0.6666em;\n}\n\n.content h3:not(:first-child) {\n  margin-top: 1.3333em;\n}\n\n.content h4 {\n  font-size: 1.25em;\n  margin-bottom: 0.8em;\n}\n\n.content h5 {\n  font-size: 1.125em;\n  margin-bottom: 0.8888em;\n}\n\n.content h6 {\n  font-size: 1em;\n  margin-bottom: 1em;\n}\n\n.content blockquote {\n  background-color: whitesmoke;\n  border-left: 5px solid #dbdbdb;\n  padding: 1.25em 1.5em;\n}\n\n.content ol {\n  list-style-position: outside;\n  margin-left: 2em;\n  margin-top: 1em;\n}\n\n.content ol:not([type]) {\n  list-style-type: decimal;\n}\n\n.content ol:not([type]).is-lower-alpha {\n  list-style-type: lower-alpha;\n}\n\n.content ol:not([type]).is-lower-roman {\n  list-style-type: lower-roman;\n}\n\n.content ol:not([type]).is-upper-alpha {\n  list-style-type: upper-alpha;\n}\n\n.content ol:not([type]).is-upper-roman {\n  list-style-type: upper-roman;\n}\n\n.content ul {\n  list-style: disc outside;\n  margin-left: 2em;\n  margin-top: 1em;\n}\n\n.content ul ul {\n  list-style-type: circle;\n  margin-top: 0.5em;\n}\n\n.content ul ul ul {\n  list-style-type: square;\n}\n\n.content dd {\n  margin-left: 2em;\n}\n\n.content figure {\n  margin-left: 2em;\n  margin-right: 2em;\n  text-align: center;\n}\n\n.content figure:not(:first-child) {\n  margin-top: 2em;\n}\n\n.content figure:not(:last-child) {\n  margin-bottom: 2em;\n}\n\n.content figure img {\n  display: inline-block;\n}\n\n.content figure figcaption {\n  font-style: italic;\n}\n\n.content pre {\n  -webkit-overflow-scrolling: touch;\n  overflow-x: auto;\n  padding: 1.25em 1.5em;\n  white-space: pre;\n  word-wrap: normal;\n}\n\n.content sup,\n.content sub {\n  font-size: 75%;\n}\n\n.content table {\n  width: 100%;\n}\n\n.content table td,\n.content table th {\n  border: 1px solid #dbdbdb;\n  border-width: 0 0 1px;\n  padding: 0.5em 0.75em;\n  vertical-align: top;\n}\n\n.content table th {\n  color: #363636;\n}\n\n.content table th:not([align]) {\n  text-align: inherit;\n}\n\n.content table thead td,\n.content table thead th {\n  border-width: 0 0 2px;\n  color: #363636;\n}\n\n.content table tfoot td,\n.content table tfoot th {\n  border-width: 2px 0 0;\n  color: #363636;\n}\n\n.content table tbody tr:last-child td,\n.content table tbody tr:last-child th {\n  border-bottom-width: 0;\n}\n\n.content .tabs li + li {\n  margin-top: 0;\n}\n\n.content.is-small {\n  font-size: 0.75rem;\n}\n\n.content.is-normal {\n  font-size: 1rem;\n}\n\n.content.is-medium {\n  font-size: 1.25rem;\n}\n\n.content.is-large {\n  font-size: 1.5rem;\n}\n\n.icon {\n  align-items: center;\n  display: inline-flex;\n  justify-content: center;\n  height: 1.5rem;\n  width: 1.5rem;\n}\n\n.icon.is-small {\n  height: 1rem;\n  width: 1rem;\n}\n\n.icon.is-medium {\n  height: 2rem;\n  width: 2rem;\n}\n\n.icon.is-large {\n  height: 3rem;\n  width: 3rem;\n}\n\n.icon-text {\n  align-items: flex-start;\n  color: inherit;\n  display: inline-flex;\n  flex-wrap: wrap;\n  line-height: 1.5rem;\n  vertical-align: top;\n}\n\n.icon-text .icon {\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.icon-text .icon:not(:last-child) {\n  margin-right: 0.25em;\n}\n\n.icon-text .icon:not(:first-child) {\n  margin-left: 0.25em;\n}\n\ndiv.icon-text {\n  display: flex;\n}\n\n.image {\n  display: block;\n  position: relative;\n}\n\n.image img {\n  display: block;\n  height: auto;\n  width: 100%;\n}\n\n.image img.is-rounded {\n  border-radius: 9999px;\n}\n\n.image.is-fullwidth {\n  width: 100%;\n}\n\n.image.is-square img,\n.image.is-square .has-ratio, .image.is-1by1 img,\n.image.is-1by1 .has-ratio, .image.is-5by4 img,\n.image.is-5by4 .has-ratio, .image.is-4by3 img,\n.image.is-4by3 .has-ratio, .image.is-3by2 img,\n.image.is-3by2 .has-ratio, .image.is-5by3 img,\n.image.is-5by3 .has-ratio, .image.is-16by9 img,\n.image.is-16by9 .has-ratio, .image.is-2by1 img,\n.image.is-2by1 .has-ratio, .image.is-3by1 img,\n.image.is-3by1 .has-ratio, .image.is-4by5 img,\n.image.is-4by5 .has-ratio, .image.is-3by4 img,\n.image.is-3by4 .has-ratio, .image.is-2by3 img,\n.image.is-2by3 .has-ratio, .image.is-3by5 img,\n.image.is-3by5 .has-ratio, .image.is-9by16 img,\n.image.is-9by16 .has-ratio, .image.is-1by2 img,\n.image.is-1by2 .has-ratio, .image.is-1by3 img,\n.image.is-1by3 .has-ratio {\n  height: 100%;\n  width: 100%;\n}\n\n.image.is-square, .image.is-1by1 {\n  padding-top: 100%;\n}\n\n.image.is-5by4 {\n  padding-top: 80%;\n}\n\n.image.is-4by3 {\n  padding-top: 75%;\n}\n\n.image.is-3by2 {\n  padding-top: 66.6666%;\n}\n\n.image.is-5by3 {\n  padding-top: 60%;\n}\n\n.image.is-16by9 {\n  padding-top: 56.25%;\n}\n\n.image.is-2by1 {\n  padding-top: 50%;\n}\n\n.image.is-3by1 {\n  padding-top: 33.3333%;\n}\n\n.image.is-4by5 {\n  padding-top: 125%;\n}\n\n.image.is-3by4 {\n  padding-top: 133.3333%;\n}\n\n.image.is-2by3 {\n  padding-top: 150%;\n}\n\n.image.is-3by5 {\n  padding-top: 166.6666%;\n}\n\n.image.is-9by16 {\n  padding-top: 177.7777%;\n}\n\n.image.is-1by2 {\n  padding-top: 200%;\n}\n\n.image.is-1by3 {\n  padding-top: 300%;\n}\n\n.image.is-16x16 {\n  height: 16px;\n  width: 16px;\n}\n\n.image.is-24x24 {\n  height: 24px;\n  width: 24px;\n}\n\n.image.is-32x32 {\n  height: 32px;\n  width: 32px;\n}\n\n.image.is-48x48 {\n  height: 48px;\n  width: 48px;\n}\n\n.image.is-64x64 {\n  height: 64px;\n  width: 64px;\n}\n\n.image.is-96x96 {\n  height: 96px;\n  width: 96px;\n}\n\n.image.is-128x128 {\n  height: 128px;\n  width: 128px;\n}\n\n.notification {\n  background-color: whitesmoke;\n  border-radius: 4px;\n  position: relative;\n  padding: 1.25rem 2.5rem 1.25rem 1.5rem;\n}\n\n.notification a:not(.button):not(.dropdown-item) {\n  color: currentColor;\n  text-decoration: underline;\n}\n\n.notification strong {\n  color: currentColor;\n}\n\n.notification code,\n.notification pre {\n  background: white;\n}\n\n.notification pre code {\n  background: transparent;\n}\n\n.notification > .delete {\n  right: 0.5rem;\n  position: absolute;\n  top: 0.5rem;\n}\n\n.notification .title,\n.notification .subtitle,\n.notification .content {\n  color: currentColor;\n}\n\n.notification.is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.notification.is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.notification.is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.notification.is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.notification.is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.notification.is-primary.is-light {\n  background-color: #ebfffc;\n  color: #00947e;\n}\n\n.notification.is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.notification.is-link.is-light {\n  background-color: #eff1fa;\n  color: #3850b7;\n}\n\n.notification.is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.notification.is-info.is-light {\n  background-color: #eff5fb;\n  color: #296fa8;\n}\n\n.notification.is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.notification.is-success.is-light {\n  background-color: #effaf5;\n  color: #257953;\n}\n\n.notification.is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.notification.is-warning.is-light {\n  background-color: #fffaeb;\n  color: #946c00;\n}\n\n.notification.is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.notification.is-danger.is-light {\n  background-color: #feecf0;\n  color: #cc0f35;\n}\n\n.progress {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  border: none;\n  border-radius: 9999px;\n  display: block;\n  height: 1rem;\n  overflow: hidden;\n  padding: 0;\n  width: 100%;\n}\n\n.progress::-webkit-progress-bar {\n  background-color: #ededed;\n}\n\n.progress::-webkit-progress-value {\n  background-color: #4a4a4a;\n}\n\n.progress::-moz-progress-bar {\n  background-color: #4a4a4a;\n}\n\n.progress::-ms-fill {\n  background-color: #4a4a4a;\n  border: none;\n}\n\n.progress.is-white::-webkit-progress-value {\n  background-color: white;\n}\n\n.progress.is-white::-moz-progress-bar {\n  background-color: white;\n}\n\n.progress.is-white::-ms-fill {\n  background-color: white;\n}\n\n.progress.is-white:indeterminate {\n  background-image: linear-gradient(to right, white 30%, #ededed 30%);\n}\n\n.progress.is-black::-webkit-progress-value {\n  background-color: #0a0a0a;\n}\n\n.progress.is-black::-moz-progress-bar {\n  background-color: #0a0a0a;\n}\n\n.progress.is-black::-ms-fill {\n  background-color: #0a0a0a;\n}\n\n.progress.is-black:indeterminate {\n  background-image: linear-gradient(to right, #0a0a0a 30%, #ededed 30%);\n}\n\n.progress.is-light::-webkit-progress-value {\n  background-color: whitesmoke;\n}\n\n.progress.is-light::-moz-progress-bar {\n  background-color: whitesmoke;\n}\n\n.progress.is-light::-ms-fill {\n  background-color: whitesmoke;\n}\n\n.progress.is-light:indeterminate {\n  background-image: linear-gradient(to right, whitesmoke 30%, #ededed 30%);\n}\n\n.progress.is-dark::-webkit-progress-value {\n  background-color: #363636;\n}\n\n.progress.is-dark::-moz-progress-bar {\n  background-color: #363636;\n}\n\n.progress.is-dark::-ms-fill {\n  background-color: #363636;\n}\n\n.progress.is-dark:indeterminate {\n  background-image: linear-gradient(to right, #363636 30%, #ededed 30%);\n}\n\n.progress.is-primary::-webkit-progress-value {\n  background-color: #00d1b2;\n}\n\n.progress.is-primary::-moz-progress-bar {\n  background-color: #00d1b2;\n}\n\n.progress.is-primary::-ms-fill {\n  background-color: #00d1b2;\n}\n\n.progress.is-primary:indeterminate {\n  background-image: linear-gradient(to right, #00d1b2 30%, #ededed 30%);\n}\n\n.progress.is-link::-webkit-progress-value {\n  background-color: #485fc7;\n}\n\n.progress.is-link::-moz-progress-bar {\n  background-color: #485fc7;\n}\n\n.progress.is-link::-ms-fill {\n  background-color: #485fc7;\n}\n\n.progress.is-link:indeterminate {\n  background-image: linear-gradient(to right, #485fc7 30%, #ededed 30%);\n}\n\n.progress.is-info::-webkit-progress-value {\n  background-color: #3e8ed0;\n}\n\n.progress.is-info::-moz-progress-bar {\n  background-color: #3e8ed0;\n}\n\n.progress.is-info::-ms-fill {\n  background-color: #3e8ed0;\n}\n\n.progress.is-info:indeterminate {\n  background-image: linear-gradient(to right, #3e8ed0 30%, #ededed 30%);\n}\n\n.progress.is-success::-webkit-progress-value {\n  background-color: #48c78e;\n}\n\n.progress.is-success::-moz-progress-bar {\n  background-color: #48c78e;\n}\n\n.progress.is-success::-ms-fill {\n  background-color: #48c78e;\n}\n\n.progress.is-success:indeterminate {\n  background-image: linear-gradient(to right, #48c78e 30%, #ededed 30%);\n}\n\n.progress.is-warning::-webkit-progress-value {\n  background-color: #ffe08a;\n}\n\n.progress.is-warning::-moz-progress-bar {\n  background-color: #ffe08a;\n}\n\n.progress.is-warning::-ms-fill {\n  background-color: #ffe08a;\n}\n\n.progress.is-warning:indeterminate {\n  background-image: linear-gradient(to right, #ffe08a 30%, #ededed 30%);\n}\n\n.progress.is-danger::-webkit-progress-value {\n  background-color: #f14668;\n}\n\n.progress.is-danger::-moz-progress-bar {\n  background-color: #f14668;\n}\n\n.progress.is-danger::-ms-fill {\n  background-color: #f14668;\n}\n\n.progress.is-danger:indeterminate {\n  background-image: linear-gradient(to right, #f14668 30%, #ededed 30%);\n}\n\n.progress:indeterminate {\n  -webkit-animation-duration: 1.5s;\n          animation-duration: 1.5s;\n  -webkit-animation-iteration-count: infinite;\n          animation-iteration-count: infinite;\n  -webkit-animation-name: moveIndeterminate;\n          animation-name: moveIndeterminate;\n  -webkit-animation-timing-function: linear;\n          animation-timing-function: linear;\n  background-color: #ededed;\n  background-image: linear-gradient(to right, #4a4a4a 30%, #ededed 30%);\n  background-position: top left;\n  background-repeat: no-repeat;\n  background-size: 150% 150%;\n}\n\n.progress:indeterminate::-webkit-progress-bar {\n  background-color: transparent;\n}\n\n.progress:indeterminate::-moz-progress-bar {\n  background-color: transparent;\n}\n\n.progress:indeterminate::-ms-fill {\n  animation-name: none;\n}\n\n.progress.is-small {\n  height: 0.75rem;\n}\n\n.progress.is-medium {\n  height: 1.25rem;\n}\n\n.progress.is-large {\n  height: 1.5rem;\n}\n\n@-webkit-keyframes moveIndeterminate {\n  from {\n    background-position: 200% 0;\n  }\n  to {\n    background-position: -200% 0;\n  }\n}\n\n@keyframes moveIndeterminate {\n  from {\n    background-position: 200% 0;\n  }\n  to {\n    background-position: -200% 0;\n  }\n}\n\n.table {\n  background-color: white;\n  color: #363636;\n}\n\n.table td,\n.table th {\n  border: 1px solid #dbdbdb;\n  border-width: 0 0 1px;\n  padding: 0.5em 0.75em;\n  vertical-align: top;\n}\n\n.table td.is-white,\n.table th.is-white {\n  background-color: white;\n  border-color: white;\n  color: #0a0a0a;\n}\n\n.table td.is-black,\n.table th.is-black {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  color: white;\n}\n\n.table td.is-light,\n.table th.is-light {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.table td.is-dark,\n.table th.is-dark {\n  background-color: #363636;\n  border-color: #363636;\n  color: #fff;\n}\n\n.table td.is-primary,\n.table th.is-primary {\n  background-color: #00d1b2;\n  border-color: #00d1b2;\n  color: #fff;\n}\n\n.table td.is-link,\n.table th.is-link {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n}\n\n.table td.is-info,\n.table th.is-info {\n  background-color: #3e8ed0;\n  border-color: #3e8ed0;\n  color: #fff;\n}\n\n.table td.is-success,\n.table th.is-success {\n  background-color: #48c78e;\n  border-color: #48c78e;\n  color: #fff;\n}\n\n.table td.is-warning,\n.table th.is-warning {\n  background-color: #ffe08a;\n  border-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.table td.is-danger,\n.table th.is-danger {\n  background-color: #f14668;\n  border-color: #f14668;\n  color: #fff;\n}\n\n.table td.is-narrow,\n.table th.is-narrow {\n  white-space: nowrap;\n  width: 1%;\n}\n\n.table td.is-selected,\n.table th.is-selected {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.table td.is-selected a,\n.table td.is-selected strong,\n.table th.is-selected a,\n.table th.is-selected strong {\n  color: currentColor;\n}\n\n.table td.is-vcentered,\n.table th.is-vcentered {\n  vertical-align: middle;\n}\n\n.table th {\n  color: #363636;\n}\n\n.table th:not([align]) {\n  text-align: left;\n}\n\n.table tr.is-selected {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.table tr.is-selected a,\n.table tr.is-selected strong {\n  color: currentColor;\n}\n\n.table tr.is-selected td,\n.table tr.is-selected th {\n  border-color: #fff;\n  color: currentColor;\n}\n\n.table thead {\n  background-color: transparent;\n}\n\n.table thead td,\n.table thead th {\n  border-width: 0 0 2px;\n  color: #363636;\n}\n\n.table tfoot {\n  background-color: transparent;\n}\n\n.table tfoot td,\n.table tfoot th {\n  border-width: 2px 0 0;\n  color: #363636;\n}\n\n.table tbody {\n  background-color: transparent;\n}\n\n.table tbody tr:last-child td,\n.table tbody tr:last-child th {\n  border-bottom-width: 0;\n}\n\n.table.is-bordered td,\n.table.is-bordered th {\n  border-width: 1px;\n}\n\n.table.is-bordered tr:last-child td,\n.table.is-bordered tr:last-child th {\n  border-bottom-width: 1px;\n}\n\n.table.is-fullwidth {\n  width: 100%;\n}\n\n.table.is-hoverable tbody tr:not(.is-selected):hover {\n  background-color: #fafafa;\n}\n\n.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover {\n  background-color: #fafafa;\n}\n\n.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even) {\n  background-color: whitesmoke;\n}\n\n.table.is-narrow td,\n.table.is-narrow th {\n  padding: 0.25em 0.5em;\n}\n\n.table.is-striped tbody tr:not(.is-selected):nth-child(even) {\n  background-color: #fafafa;\n}\n\n.table-container {\n  -webkit-overflow-scrolling: touch;\n  overflow: auto;\n  overflow-y: hidden;\n  max-width: 100%;\n}\n\n.tags {\n  align-items: center;\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n\n.tags .tag {\n  margin-bottom: 0.5rem;\n}\n\n.tags .tag:not(:last-child) {\n  margin-right: 0.5rem;\n}\n\n.tags:last-child {\n  margin-bottom: -0.5rem;\n}\n\n.tags:not(:last-child) {\n  margin-bottom: 1rem;\n}\n\n.tags.are-medium .tag:not(.is-normal):not(.is-large) {\n  font-size: 1rem;\n}\n\n.tags.are-large .tag:not(.is-normal):not(.is-medium) {\n  font-size: 1.25rem;\n}\n\n.tags.is-centered {\n  justify-content: center;\n}\n\n.tags.is-centered .tag {\n  margin-right: 0.25rem;\n  margin-left: 0.25rem;\n}\n\n.tags.is-right {\n  justify-content: flex-end;\n}\n\n.tags.is-right .tag:not(:first-child) {\n  margin-left: 0.5rem;\n}\n\n.tags.is-right .tag:not(:last-child) {\n  margin-right: 0;\n}\n\n.tags.has-addons .tag {\n  margin-right: 0;\n}\n\n.tags.has-addons .tag:not(:first-child) {\n  margin-left: 0;\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.tags.has-addons .tag:not(:last-child) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n\n.tag:not(body) {\n  align-items: center;\n  background-color: whitesmoke;\n  border-radius: 4px;\n  color: #4a4a4a;\n  display: inline-flex;\n  font-size: 0.75rem;\n  height: 2em;\n  justify-content: center;\n  line-height: 1.5;\n  padding-left: 0.75em;\n  padding-right: 0.75em;\n  white-space: nowrap;\n}\n\n.tag:not(body) .delete {\n  margin-left: 0.25rem;\n  margin-right: -0.375rem;\n}\n\n.tag:not(body).is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.tag:not(body).is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.tag:not(body).is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.tag:not(body).is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.tag:not(body).is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.tag:not(body).is-primary.is-light {\n  background-color: #ebfffc;\n  color: #00947e;\n}\n\n.tag:not(body).is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.tag:not(body).is-link.is-light {\n  background-color: #eff1fa;\n  color: #3850b7;\n}\n\n.tag:not(body).is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.tag:not(body).is-info.is-light {\n  background-color: #eff5fb;\n  color: #296fa8;\n}\n\n.tag:not(body).is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.tag:not(body).is-success.is-light {\n  background-color: #effaf5;\n  color: #257953;\n}\n\n.tag:not(body).is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.tag:not(body).is-warning.is-light {\n  background-color: #fffaeb;\n  color: #946c00;\n}\n\n.tag:not(body).is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.tag:not(body).is-danger.is-light {\n  background-color: #feecf0;\n  color: #cc0f35;\n}\n\n.tag:not(body).is-normal {\n  font-size: 0.75rem;\n}\n\n.tag:not(body).is-medium {\n  font-size: 1rem;\n}\n\n.tag:not(body).is-large {\n  font-size: 1.25rem;\n}\n\n.tag:not(body) .icon:first-child:not(:last-child) {\n  margin-left: -0.375em;\n  margin-right: 0.1875em;\n}\n\n.tag:not(body) .icon:last-child:not(:first-child) {\n  margin-left: 0.1875em;\n  margin-right: -0.375em;\n}\n\n.tag:not(body) .icon:first-child:last-child {\n  margin-left: -0.375em;\n  margin-right: -0.375em;\n}\n\n.tag:not(body).is-delete {\n  margin-left: 1px;\n  padding: 0;\n  position: relative;\n  width: 2em;\n}\n\n.tag:not(body).is-delete::before, .tag:not(body).is-delete::after {\n  background-color: currentColor;\n  content: \"\";\n  display: block;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translateX(-50%) translateY(-50%) rotate(45deg);\n  transform-origin: center center;\n}\n\n.tag:not(body).is-delete::before {\n  height: 1px;\n  width: 50%;\n}\n\n.tag:not(body).is-delete::after {\n  height: 50%;\n  width: 1px;\n}\n\n.tag:not(body).is-delete:hover, .tag:not(body).is-delete:focus {\n  background-color: #e8e8e8;\n}\n\n.tag:not(body).is-delete:active {\n  background-color: #dbdbdb;\n}\n\n.tag:not(body).is-rounded {\n  border-radius: 9999px;\n}\n\na.tag:hover {\n  text-decoration: underline;\n}\n\n.title,\n.subtitle {\n  word-break: break-word;\n}\n\n.title em,\n.title span,\n.subtitle em,\n.subtitle span {\n  font-weight: inherit;\n}\n\n.title sub,\n.subtitle sub {\n  font-size: 0.75em;\n}\n\n.title sup,\n.subtitle sup {\n  font-size: 0.75em;\n}\n\n.title .tag,\n.subtitle .tag {\n  vertical-align: middle;\n}\n\n.title {\n  color: #363636;\n  font-size: 2rem;\n  font-weight: 600;\n  line-height: 1.125;\n}\n\n.title strong {\n  color: inherit;\n  font-weight: inherit;\n}\n\n.title:not(.is-spaced) + .subtitle {\n  margin-top: -1.25rem;\n}\n\n.title.is-1 {\n  font-size: 3rem;\n}\n\n.title.is-2 {\n  font-size: 2.5rem;\n}\n\n.title.is-3 {\n  font-size: 2rem;\n}\n\n.title.is-4 {\n  font-size: 1.5rem;\n}\n\n.title.is-5 {\n  font-size: 1.25rem;\n}\n\n.title.is-6 {\n  font-size: 1rem;\n}\n\n.title.is-7 {\n  font-size: 0.75rem;\n}\n\n.subtitle {\n  color: #4a4a4a;\n  font-size: 1.25rem;\n  font-weight: 400;\n  line-height: 1.25;\n}\n\n.subtitle strong {\n  color: #363636;\n  font-weight: 600;\n}\n\n.subtitle:not(.is-spaced) + .title {\n  margin-top: -1.25rem;\n}\n\n.subtitle.is-1 {\n  font-size: 3rem;\n}\n\n.subtitle.is-2 {\n  font-size: 2.5rem;\n}\n\n.subtitle.is-3 {\n  font-size: 2rem;\n}\n\n.subtitle.is-4 {\n  font-size: 1.5rem;\n}\n\n.subtitle.is-5 {\n  font-size: 1.25rem;\n}\n\n.subtitle.is-6 {\n  font-size: 1rem;\n}\n\n.subtitle.is-7 {\n  font-size: 0.75rem;\n}\n\n.heading {\n  display: block;\n  font-size: 11px;\n  letter-spacing: 1px;\n  margin-bottom: 5px;\n  text-transform: uppercase;\n}\n\n.number {\n  align-items: center;\n  background-color: whitesmoke;\n  border-radius: 9999px;\n  display: inline-flex;\n  font-size: 1.25rem;\n  height: 2em;\n  justify-content: center;\n  margin-right: 1.5rem;\n  min-width: 2.5em;\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  vertical-align: top;\n}\n\n/* Bulma Form */\n.input, .textarea, .select select {\n  background-color: white;\n  border-color: #dbdbdb;\n  border-radius: 4px;\n  color: #363636;\n}\n\n.input::-moz-placeholder, .textarea::-moz-placeholder, .select select::-moz-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input::-webkit-input-placeholder, .textarea::-webkit-input-placeholder, .select select::-webkit-input-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input:-moz-placeholder, .textarea:-moz-placeholder, .select select:-moz-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input:-ms-input-placeholder, .textarea:-ms-input-placeholder, .select select:-ms-input-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input:hover, .textarea:hover, .select select:hover, .is-hovered.input, .is-hovered.textarea, .select select.is-hovered {\n  border-color: #b5b5b5;\n}\n\n.input:focus, .textarea:focus, .select select:focus, .is-focused.input, .is-focused.textarea, .select select.is-focused, .input:active, .textarea:active, .select select:active, .is-active.input, .is-active.textarea, .select select.is-active {\n  border-color: #485fc7;\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.input[disabled], .textarea[disabled], .select select[disabled],\nfieldset[disabled] .input,\nfieldset[disabled] .textarea,\nfieldset[disabled] .select select,\n.select fieldset[disabled] select {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  box-shadow: none;\n  color: #7a7a7a;\n}\n\n.input[disabled]::-moz-placeholder, .textarea[disabled]::-moz-placeholder, .select select[disabled]::-moz-placeholder,\nfieldset[disabled] .input::-moz-placeholder,\nfieldset[disabled] .textarea::-moz-placeholder,\nfieldset[disabled] .select select::-moz-placeholder,\n.select fieldset[disabled] select::-moz-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input[disabled]::-webkit-input-placeholder, .textarea[disabled]::-webkit-input-placeholder, .select select[disabled]::-webkit-input-placeholder,\nfieldset[disabled] .input::-webkit-input-placeholder,\nfieldset[disabled] .textarea::-webkit-input-placeholder,\nfieldset[disabled] .select select::-webkit-input-placeholder,\n.select fieldset[disabled] select::-webkit-input-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input[disabled]:-moz-placeholder, .textarea[disabled]:-moz-placeholder, .select select[disabled]:-moz-placeholder,\nfieldset[disabled] .input:-moz-placeholder,\nfieldset[disabled] .textarea:-moz-placeholder,\nfieldset[disabled] .select select:-moz-placeholder,\n.select fieldset[disabled] select:-moz-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input[disabled]:-ms-input-placeholder, .textarea[disabled]:-ms-input-placeholder, .select select[disabled]:-ms-input-placeholder,\nfieldset[disabled] .input:-ms-input-placeholder,\nfieldset[disabled] .textarea:-ms-input-placeholder,\nfieldset[disabled] .select select:-ms-input-placeholder,\n.select fieldset[disabled] select:-ms-input-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input, .textarea {\n  box-shadow: inset 0 0.0625em 0.125em rgba(10, 10, 10, 0.05);\n  max-width: 100%;\n  width: 100%;\n}\n\n.input[readonly], .textarea[readonly] {\n  box-shadow: none;\n}\n\n.is-white.input, .is-white.textarea {\n  border-color: white;\n}\n\n.is-white.input:focus, .is-white.textarea:focus, .is-white.is-focused.input, .is-white.is-focused.textarea, .is-white.input:active, .is-white.textarea:active, .is-white.is-active.input, .is-white.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25);\n}\n\n.is-black.input, .is-black.textarea {\n  border-color: #0a0a0a;\n}\n\n.is-black.input:focus, .is-black.textarea:focus, .is-black.is-focused.input, .is-black.is-focused.textarea, .is-black.input:active, .is-black.textarea:active, .is-black.is-active.input, .is-black.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25);\n}\n\n.is-light.input, .is-light.textarea {\n  border-color: whitesmoke;\n}\n\n.is-light.input:focus, .is-light.textarea:focus, .is-light.is-focused.input, .is-light.is-focused.textarea, .is-light.input:active, .is-light.textarea:active, .is-light.is-active.input, .is-light.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25);\n}\n\n.is-dark.input, .is-dark.textarea {\n  border-color: #363636;\n}\n\n.is-dark.input:focus, .is-dark.textarea:focus, .is-dark.is-focused.input, .is-dark.is-focused.textarea, .is-dark.input:active, .is-dark.textarea:active, .is-dark.is-active.input, .is-dark.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25);\n}\n\n.is-primary.input, .is-primary.textarea {\n  border-color: #00d1b2;\n}\n\n.is-primary.input:focus, .is-primary.textarea:focus, .is-primary.is-focused.input, .is-primary.is-focused.textarea, .is-primary.input:active, .is-primary.textarea:active, .is-primary.is-active.input, .is-primary.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25);\n}\n\n.is-link.input, .is-link.textarea {\n  border-color: #485fc7;\n}\n\n.is-link.input:focus, .is-link.textarea:focus, .is-link.is-focused.input, .is-link.is-focused.textarea, .is-link.input:active, .is-link.textarea:active, .is-link.is-active.input, .is-link.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.is-info.input, .is-info.textarea {\n  border-color: #3e8ed0;\n}\n\n.is-info.input:focus, .is-info.textarea:focus, .is-info.is-focused.input, .is-info.is-focused.textarea, .is-info.input:active, .is-info.textarea:active, .is-info.is-active.input, .is-info.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(62, 142, 208, 0.25);\n}\n\n.is-success.input, .is-success.textarea {\n  border-color: #48c78e;\n}\n\n.is-success.input:focus, .is-success.textarea:focus, .is-success.is-focused.input, .is-success.is-focused.textarea, .is-success.input:active, .is-success.textarea:active, .is-success.is-active.input, .is-success.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(72, 199, 142, 0.25);\n}\n\n.is-warning.input, .is-warning.textarea {\n  border-color: #ffe08a;\n}\n\n.is-warning.input:focus, .is-warning.textarea:focus, .is-warning.is-focused.input, .is-warning.is-focused.textarea, .is-warning.input:active, .is-warning.textarea:active, .is-warning.is-active.input, .is-warning.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(255, 224, 138, 0.25);\n}\n\n.is-danger.input, .is-danger.textarea {\n  border-color: #f14668;\n}\n\n.is-danger.input:focus, .is-danger.textarea:focus, .is-danger.is-focused.input, .is-danger.is-focused.textarea, .is-danger.input:active, .is-danger.textarea:active, .is-danger.is-active.input, .is-danger.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25);\n}\n\n.is-small.input, .is-small.textarea {\n  border-radius: 2px;\n  font-size: 0.75rem;\n}\n\n.is-medium.input, .is-medium.textarea {\n  font-size: 1.25rem;\n}\n\n.is-large.input, .is-large.textarea {\n  font-size: 1.5rem;\n}\n\n.is-fullwidth.input, .is-fullwidth.textarea {\n  display: block;\n  width: 100%;\n}\n\n.is-inline.input, .is-inline.textarea {\n  display: inline;\n  width: auto;\n}\n\n.input.is-rounded {\n  border-radius: 9999px;\n  padding-left: calc(calc(0.75em - 1px) + 0.375em);\n  padding-right: calc(calc(0.75em - 1px) + 0.375em);\n}\n\n.input.is-static {\n  background-color: transparent;\n  border-color: transparent;\n  box-shadow: none;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n.textarea {\n  display: block;\n  max-width: 100%;\n  min-width: 100%;\n  padding: calc(0.75em - 1px);\n  resize: vertical;\n}\n\n.textarea:not([rows]) {\n  max-height: 40em;\n  min-height: 8em;\n}\n\n.textarea[rows] {\n  height: initial;\n}\n\n.textarea.has-fixed-size {\n  resize: none;\n}\n\n.checkbox, .radio {\n  cursor: pointer;\n  display: inline-block;\n  line-height: 1.25;\n  position: relative;\n}\n\n.checkbox input, .radio input {\n  cursor: pointer;\n}\n\n.checkbox:hover, .radio:hover {\n  color: #363636;\n}\n\n.checkbox[disabled], .radio[disabled],\nfieldset[disabled] .checkbox,\nfieldset[disabled] .radio,\n.checkbox input[disabled],\n.radio input[disabled] {\n  color: #7a7a7a;\n  cursor: not-allowed;\n}\n\n.radio + .radio {\n  margin-left: 0.5em;\n}\n\n.select {\n  display: inline-block;\n  max-width: 100%;\n  position: relative;\n  vertical-align: top;\n}\n\n.select:not(.is-multiple) {\n  height: 2.5em;\n}\n\n.select:not(.is-multiple):not(.is-loading)::after {\n  border-color: #485fc7;\n  right: 1.125em;\n  z-index: 4;\n}\n\n.select.is-rounded select {\n  border-radius: 9999px;\n  padding-left: 1em;\n}\n\n.select select {\n  cursor: pointer;\n  display: block;\n  font-size: 1em;\n  max-width: 100%;\n  outline: none;\n}\n\n.select select::-ms-expand {\n  display: none;\n}\n\n.select select[disabled]:hover,\nfieldset[disabled] .select select:hover {\n  border-color: whitesmoke;\n}\n\n.select select:not([multiple]) {\n  padding-right: 2.5em;\n}\n\n.select select[multiple] {\n  height: auto;\n  padding: 0;\n}\n\n.select select[multiple] option {\n  padding: 0.5em 1em;\n}\n\n.select:not(.is-multiple):not(.is-loading):hover::after {\n  border-color: #363636;\n}\n\n.select.is-white:not(:hover)::after {\n  border-color: white;\n}\n\n.select.is-white select {\n  border-color: white;\n}\n\n.select.is-white select:hover, .select.is-white select.is-hovered {\n  border-color: #f2f2f2;\n}\n\n.select.is-white select:focus, .select.is-white select.is-focused, .select.is-white select:active, .select.is-white select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25);\n}\n\n.select.is-black:not(:hover)::after {\n  border-color: #0a0a0a;\n}\n\n.select.is-black select {\n  border-color: #0a0a0a;\n}\n\n.select.is-black select:hover, .select.is-black select.is-hovered {\n  border-color: black;\n}\n\n.select.is-black select:focus, .select.is-black select.is-focused, .select.is-black select:active, .select.is-black select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25);\n}\n\n.select.is-light:not(:hover)::after {\n  border-color: whitesmoke;\n}\n\n.select.is-light select {\n  border-color: whitesmoke;\n}\n\n.select.is-light select:hover, .select.is-light select.is-hovered {\n  border-color: #e8e8e8;\n}\n\n.select.is-light select:focus, .select.is-light select.is-focused, .select.is-light select:active, .select.is-light select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25);\n}\n\n.select.is-dark:not(:hover)::after {\n  border-color: #363636;\n}\n\n.select.is-dark select {\n  border-color: #363636;\n}\n\n.select.is-dark select:hover, .select.is-dark select.is-hovered {\n  border-color: #292929;\n}\n\n.select.is-dark select:focus, .select.is-dark select.is-focused, .select.is-dark select:active, .select.is-dark select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25);\n}\n\n.select.is-primary:not(:hover)::after {\n  border-color: #00d1b2;\n}\n\n.select.is-primary select {\n  border-color: #00d1b2;\n}\n\n.select.is-primary select:hover, .select.is-primary select.is-hovered {\n  border-color: #00b89c;\n}\n\n.select.is-primary select:focus, .select.is-primary select.is-focused, .select.is-primary select:active, .select.is-primary select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25);\n}\n\n.select.is-link:not(:hover)::after {\n  border-color: #485fc7;\n}\n\n.select.is-link select {\n  border-color: #485fc7;\n}\n\n.select.is-link select:hover, .select.is-link select.is-hovered {\n  border-color: #3a51bb;\n}\n\n.select.is-link select:focus, .select.is-link select.is-focused, .select.is-link select:active, .select.is-link select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.select.is-info:not(:hover)::after {\n  border-color: #3e8ed0;\n}\n\n.select.is-info select {\n  border-color: #3e8ed0;\n}\n\n.select.is-info select:hover, .select.is-info select.is-hovered {\n  border-color: #3082c5;\n}\n\n.select.is-info select:focus, .select.is-info select.is-focused, .select.is-info select:active, .select.is-info select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(62, 142, 208, 0.25);\n}\n\n.select.is-success:not(:hover)::after {\n  border-color: #48c78e;\n}\n\n.select.is-success select {\n  border-color: #48c78e;\n}\n\n.select.is-success select:hover, .select.is-success select.is-hovered {\n  border-color: #3abb81;\n}\n\n.select.is-success select:focus, .select.is-success select.is-focused, .select.is-success select:active, .select.is-success select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(72, 199, 142, 0.25);\n}\n\n.select.is-warning:not(:hover)::after {\n  border-color: #ffe08a;\n}\n\n.select.is-warning select {\n  border-color: #ffe08a;\n}\n\n.select.is-warning select:hover, .select.is-warning select.is-hovered {\n  border-color: #ffd970;\n}\n\n.select.is-warning select:focus, .select.is-warning select.is-focused, .select.is-warning select:active, .select.is-warning select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(255, 224, 138, 0.25);\n}\n\n.select.is-danger:not(:hover)::after {\n  border-color: #f14668;\n}\n\n.select.is-danger select {\n  border-color: #f14668;\n}\n\n.select.is-danger select:hover, .select.is-danger select.is-hovered {\n  border-color: #ef2e55;\n}\n\n.select.is-danger select:focus, .select.is-danger select.is-focused, .select.is-danger select:active, .select.is-danger select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25);\n}\n\n.select.is-small {\n  border-radius: 2px;\n  font-size: 0.75rem;\n}\n\n.select.is-medium {\n  font-size: 1.25rem;\n}\n\n.select.is-large {\n  font-size: 1.5rem;\n}\n\n.select.is-disabled::after {\n  border-color: #7a7a7a !important;\n  opacity: 0.5;\n}\n\n.select.is-fullwidth {\n  width: 100%;\n}\n\n.select.is-fullwidth select {\n  width: 100%;\n}\n\n.select.is-loading::after {\n  margin-top: 0;\n  position: absolute;\n  right: 0.625em;\n  top: 0.625em;\n  transform: none;\n}\n\n.select.is-loading.is-small:after {\n  font-size: 0.75rem;\n}\n\n.select.is-loading.is-medium:after {\n  font-size: 1.25rem;\n}\n\n.select.is-loading.is-large:after {\n  font-size: 1.5rem;\n}\n\n.file {\n  align-items: stretch;\n  display: flex;\n  justify-content: flex-start;\n  position: relative;\n}\n\n.file.is-white .file-cta {\n  background-color: white;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.file.is-white:hover .file-cta, .file.is-white.is-hovered .file-cta {\n  background-color: #f9f9f9;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.file.is-white:focus .file-cta, .file.is-white.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(255, 255, 255, 0.25);\n  color: #0a0a0a;\n}\n\n.file.is-white:active .file-cta, .file.is-white.is-active .file-cta {\n  background-color: #f2f2f2;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.file.is-black .file-cta {\n  background-color: #0a0a0a;\n  border-color: transparent;\n  color: white;\n}\n\n.file.is-black:hover .file-cta, .file.is-black.is-hovered .file-cta {\n  background-color: #040404;\n  border-color: transparent;\n  color: white;\n}\n\n.file.is-black:focus .file-cta, .file.is-black.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(10, 10, 10, 0.25);\n  color: white;\n}\n\n.file.is-black:active .file-cta, .file.is-black.is-active .file-cta {\n  background-color: black;\n  border-color: transparent;\n  color: white;\n}\n\n.file.is-light .file-cta {\n  background-color: whitesmoke;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-light:hover .file-cta, .file.is-light.is-hovered .file-cta {\n  background-color: #eeeeee;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-light:focus .file-cta, .file.is-light.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(245, 245, 245, 0.25);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-light:active .file-cta, .file.is-light.is-active .file-cta {\n  background-color: #e8e8e8;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-dark .file-cta {\n  background-color: #363636;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-dark:hover .file-cta, .file.is-dark.is-hovered .file-cta {\n  background-color: #2f2f2f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-dark:focus .file-cta, .file.is-dark.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(54, 54, 54, 0.25);\n  color: #fff;\n}\n\n.file.is-dark:active .file-cta, .file.is-dark.is-active .file-cta {\n  background-color: #292929;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-primary .file-cta {\n  background-color: #00d1b2;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-primary:hover .file-cta, .file.is-primary.is-hovered .file-cta {\n  background-color: #00c4a7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-primary:focus .file-cta, .file.is-primary.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(0, 209, 178, 0.25);\n  color: #fff;\n}\n\n.file.is-primary:active .file-cta, .file.is-primary.is-active .file-cta {\n  background-color: #00b89c;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-link .file-cta {\n  background-color: #485fc7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-link:hover .file-cta, .file.is-link.is-hovered .file-cta {\n  background-color: #3e56c4;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-link:focus .file-cta, .file.is-link.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(72, 95, 199, 0.25);\n  color: #fff;\n}\n\n.file.is-link:active .file-cta, .file.is-link.is-active .file-cta {\n  background-color: #3a51bb;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-info .file-cta {\n  background-color: #3e8ed0;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-info:hover .file-cta, .file.is-info.is-hovered .file-cta {\n  background-color: #3488ce;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-info:focus .file-cta, .file.is-info.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(62, 142, 208, 0.25);\n  color: #fff;\n}\n\n.file.is-info:active .file-cta, .file.is-info.is-active .file-cta {\n  background-color: #3082c5;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-success .file-cta {\n  background-color: #48c78e;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-success:hover .file-cta, .file.is-success.is-hovered .file-cta {\n  background-color: #3ec487;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-success:focus .file-cta, .file.is-success.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(72, 199, 142, 0.25);\n  color: #fff;\n}\n\n.file.is-success:active .file-cta, .file.is-success.is-active .file-cta {\n  background-color: #3abb81;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-warning .file-cta {\n  background-color: #ffe08a;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-warning:hover .file-cta, .file.is-warning.is-hovered .file-cta {\n  background-color: #ffdc7d;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-warning:focus .file-cta, .file.is-warning.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(255, 224, 138, 0.25);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-warning:active .file-cta, .file.is-warning.is-active .file-cta {\n  background-color: #ffd970;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-danger .file-cta {\n  background-color: #f14668;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-danger:hover .file-cta, .file.is-danger.is-hovered .file-cta {\n  background-color: #f03a5f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-danger:focus .file-cta, .file.is-danger.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(241, 70, 104, 0.25);\n  color: #fff;\n}\n\n.file.is-danger:active .file-cta, .file.is-danger.is-active .file-cta {\n  background-color: #ef2e55;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-small {\n  font-size: 0.75rem;\n}\n\n.file.is-normal {\n  font-size: 1rem;\n}\n\n.file.is-medium {\n  font-size: 1.25rem;\n}\n\n.file.is-medium .file-icon .fa {\n  font-size: 21px;\n}\n\n.file.is-large {\n  font-size: 1.5rem;\n}\n\n.file.is-large .file-icon .fa {\n  font-size: 28px;\n}\n\n.file.has-name .file-cta {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.file.has-name .file-name {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.file.has-name.is-empty .file-cta {\n  border-radius: 4px;\n}\n\n.file.has-name.is-empty .file-name {\n  display: none;\n}\n\n.file.is-boxed .file-label {\n  flex-direction: column;\n}\n\n.file.is-boxed .file-cta {\n  flex-direction: column;\n  height: auto;\n  padding: 1em 3em;\n}\n\n.file.is-boxed .file-name {\n  border-width: 0 1px 1px;\n}\n\n.file.is-boxed .file-icon {\n  height: 1.5em;\n  width: 1.5em;\n}\n\n.file.is-boxed .file-icon .fa {\n  font-size: 21px;\n}\n\n.file.is-boxed.is-small .file-icon .fa {\n  font-size: 14px;\n}\n\n.file.is-boxed.is-medium .file-icon .fa {\n  font-size: 28px;\n}\n\n.file.is-boxed.is-large .file-icon .fa {\n  font-size: 35px;\n}\n\n.file.is-boxed.has-name .file-cta {\n  border-radius: 4px 4px 0 0;\n}\n\n.file.is-boxed.has-name .file-name {\n  border-radius: 0 0 4px 4px;\n  border-width: 0 1px 1px;\n}\n\n.file.is-centered {\n  justify-content: center;\n}\n\n.file.is-fullwidth .file-label {\n  width: 100%;\n}\n\n.file.is-fullwidth .file-name {\n  flex-grow: 1;\n  max-width: none;\n}\n\n.file.is-right {\n  justify-content: flex-end;\n}\n\n.file.is-right .file-cta {\n  border-radius: 0 4px 4px 0;\n}\n\n.file.is-right .file-name {\n  border-radius: 4px 0 0 4px;\n  border-width: 1px 0 1px 1px;\n  order: -1;\n}\n\n.file-label {\n  align-items: stretch;\n  display: flex;\n  cursor: pointer;\n  justify-content: flex-start;\n  overflow: hidden;\n  position: relative;\n}\n\n.file-label:hover .file-cta {\n  background-color: #eeeeee;\n  color: #363636;\n}\n\n.file-label:hover .file-name {\n  border-color: #d5d5d5;\n}\n\n.file-label:active .file-cta {\n  background-color: #e8e8e8;\n  color: #363636;\n}\n\n.file-label:active .file-name {\n  border-color: #cfcfcf;\n}\n\n.file-input {\n  height: 100%;\n  left: 0;\n  opacity: 0;\n  outline: none;\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n\n.file-cta,\n.file-name {\n  border-color: #dbdbdb;\n  border-radius: 4px;\n  font-size: 1em;\n  padding-left: 1em;\n  padding-right: 1em;\n  white-space: nowrap;\n}\n\n.file-cta {\n  background-color: whitesmoke;\n  color: #4a4a4a;\n}\n\n.file-name {\n  border-color: #dbdbdb;\n  border-style: solid;\n  border-width: 1px 1px 1px 0;\n  display: block;\n  max-width: 16em;\n  overflow: hidden;\n  text-align: inherit;\n  text-overflow: ellipsis;\n}\n\n.file-icon {\n  align-items: center;\n  display: flex;\n  height: 1em;\n  justify-content: center;\n  margin-right: 0.5em;\n  width: 1em;\n}\n\n.file-icon .fa {\n  font-size: 14px;\n}\n\n.label {\n  color: #363636;\n  display: block;\n  font-size: 1rem;\n  font-weight: 700;\n}\n\n.label:not(:last-child) {\n  margin-bottom: 0.5em;\n}\n\n.label.is-small {\n  font-size: 0.75rem;\n}\n\n.label.is-medium {\n  font-size: 1.25rem;\n}\n\n.label.is-large {\n  font-size: 1.5rem;\n}\n\n.help {\n  display: block;\n  font-size: 0.75rem;\n  margin-top: 0.25rem;\n}\n\n.help.is-white {\n  color: white;\n}\n\n.help.is-black {\n  color: #0a0a0a;\n}\n\n.help.is-light {\n  color: whitesmoke;\n}\n\n.help.is-dark {\n  color: #363636;\n}\n\n.help.is-primary {\n  color: #00d1b2;\n}\n\n.help.is-link {\n  color: #485fc7;\n}\n\n.help.is-info {\n  color: #3e8ed0;\n}\n\n.help.is-success {\n  color: #48c78e;\n}\n\n.help.is-warning {\n  color: #ffe08a;\n}\n\n.help.is-danger {\n  color: #f14668;\n}\n\n.field:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.field.has-addons {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.field.has-addons .control:not(:last-child) {\n  margin-right: -1px;\n}\n\n.field.has-addons .control:not(:first-child):not(:last-child) .button,\n.field.has-addons .control:not(:first-child):not(:last-child) .input,\n.field.has-addons .control:not(:first-child):not(:last-child) .select select {\n  border-radius: 0;\n}\n\n.field.has-addons .control:first-child:not(:only-child) .button,\n.field.has-addons .control:first-child:not(:only-child) .input,\n.field.has-addons .control:first-child:not(:only-child) .select select {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.field.has-addons .control:last-child:not(:only-child) .button,\n.field.has-addons .control:last-child:not(:only-child) .input,\n.field.has-addons .control:last-child:not(:only-child) .select select {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.field.has-addons .control .button:not([disabled]):hover, .field.has-addons .control .button:not([disabled]).is-hovered,\n.field.has-addons .control .input:not([disabled]):hover,\n.field.has-addons .control .input:not([disabled]).is-hovered,\n.field.has-addons .control .select select:not([disabled]):hover,\n.field.has-addons .control .select select:not([disabled]).is-hovered {\n  z-index: 2;\n}\n\n.field.has-addons .control .button:not([disabled]):focus, .field.has-addons .control .button:not([disabled]).is-focused, .field.has-addons .control .button:not([disabled]):active, .field.has-addons .control .button:not([disabled]).is-active,\n.field.has-addons .control .input:not([disabled]):focus,\n.field.has-addons .control .input:not([disabled]).is-focused,\n.field.has-addons .control .input:not([disabled]):active,\n.field.has-addons .control .input:not([disabled]).is-active,\n.field.has-addons .control .select select:not([disabled]):focus,\n.field.has-addons .control .select select:not([disabled]).is-focused,\n.field.has-addons .control .select select:not([disabled]):active,\n.field.has-addons .control .select select:not([disabled]).is-active {\n  z-index: 3;\n}\n\n.field.has-addons .control .button:not([disabled]):focus:hover, .field.has-addons .control .button:not([disabled]).is-focused:hover, .field.has-addons .control .button:not([disabled]):active:hover, .field.has-addons .control .button:not([disabled]).is-active:hover,\n.field.has-addons .control .input:not([disabled]):focus:hover,\n.field.has-addons .control .input:not([disabled]).is-focused:hover,\n.field.has-addons .control .input:not([disabled]):active:hover,\n.field.has-addons .control .input:not([disabled]).is-active:hover,\n.field.has-addons .control .select select:not([disabled]):focus:hover,\n.field.has-addons .control .select select:not([disabled]).is-focused:hover,\n.field.has-addons .control .select select:not([disabled]):active:hover,\n.field.has-addons .control .select select:not([disabled]).is-active:hover {\n  z-index: 4;\n}\n\n.field.has-addons .control.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.field.has-addons.has-addons-centered {\n  justify-content: center;\n}\n\n.field.has-addons.has-addons-right {\n  justify-content: flex-end;\n}\n\n.field.has-addons.has-addons-fullwidth .control {\n  flex-grow: 1;\n  flex-shrink: 0;\n}\n\n.field.is-grouped {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.field.is-grouped > .control {\n  flex-shrink: 0;\n}\n\n.field.is-grouped > .control:not(:last-child) {\n  margin-bottom: 0;\n  margin-right: 0.75rem;\n}\n\n.field.is-grouped > .control.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.field.is-grouped.is-grouped-centered {\n  justify-content: center;\n}\n\n.field.is-grouped.is-grouped-right {\n  justify-content: flex-end;\n}\n\n.field.is-grouped.is-grouped-multiline {\n  flex-wrap: wrap;\n}\n\n.field.is-grouped.is-grouped-multiline > .control:last-child, .field.is-grouped.is-grouped-multiline > .control:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.field.is-grouped.is-grouped-multiline:last-child {\n  margin-bottom: -0.75rem;\n}\n\n.field.is-grouped.is-grouped-multiline:not(:last-child) {\n  margin-bottom: 0;\n}\n\n@media screen and (min-width: 769px), print {\n  .field.is-horizontal {\n    display: flex;\n  }\n}\n\n.field-label .label {\n  font-size: inherit;\n}\n\n@media screen and (max-width: 768px) {\n  .field-label {\n    margin-bottom: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .field-label {\n    flex-basis: 0;\n    flex-grow: 1;\n    flex-shrink: 0;\n    margin-right: 1.5rem;\n    text-align: right;\n  }\n  .field-label.is-small {\n    font-size: 0.75rem;\n    padding-top: 0.375em;\n  }\n  .field-label.is-normal {\n    padding-top: 0.375em;\n  }\n  .field-label.is-medium {\n    font-size: 1.25rem;\n    padding-top: 0.375em;\n  }\n  .field-label.is-large {\n    font-size: 1.5rem;\n    padding-top: 0.375em;\n  }\n}\n\n.field-body .field .field {\n  margin-bottom: 0;\n}\n\n@media screen and (min-width: 769px), print {\n  .field-body {\n    display: flex;\n    flex-basis: 0;\n    flex-grow: 5;\n    flex-shrink: 1;\n  }\n  .field-body .field {\n    margin-bottom: 0;\n  }\n  .field-body > .field {\n    flex-shrink: 1;\n  }\n  .field-body > .field:not(.is-narrow) {\n    flex-grow: 1;\n  }\n  .field-body > .field:not(:last-child) {\n    margin-right: 0.75rem;\n  }\n}\n\n.control {\n  box-sizing: border-box;\n  clear: both;\n  font-size: 1rem;\n  position: relative;\n  text-align: inherit;\n}\n\n.control.has-icons-left .input:focus ~ .icon,\n.control.has-icons-left .select:focus ~ .icon, .control.has-icons-right .input:focus ~ .icon,\n.control.has-icons-right .select:focus ~ .icon {\n  color: #4a4a4a;\n}\n\n.control.has-icons-left .input.is-small ~ .icon,\n.control.has-icons-left .select.is-small ~ .icon, .control.has-icons-right .input.is-small ~ .icon,\n.control.has-icons-right .select.is-small ~ .icon {\n  font-size: 0.75rem;\n}\n\n.control.has-icons-left .input.is-medium ~ .icon,\n.control.has-icons-left .select.is-medium ~ .icon, .control.has-icons-right .input.is-medium ~ .icon,\n.control.has-icons-right .select.is-medium ~ .icon {\n  font-size: 1.25rem;\n}\n\n.control.has-icons-left .input.is-large ~ .icon,\n.control.has-icons-left .select.is-large ~ .icon, .control.has-icons-right .input.is-large ~ .icon,\n.control.has-icons-right .select.is-large ~ .icon {\n  font-size: 1.5rem;\n}\n\n.control.has-icons-left .icon, .control.has-icons-right .icon {\n  color: #dbdbdb;\n  height: 2.5em;\n  pointer-events: none;\n  position: absolute;\n  top: 0;\n  width: 2.5em;\n  z-index: 4;\n}\n\n.control.has-icons-left .input,\n.control.has-icons-left .select select {\n  padding-left: 2.5em;\n}\n\n.control.has-icons-left .icon.is-left {\n  left: 0;\n}\n\n.control.has-icons-right .input,\n.control.has-icons-right .select select {\n  padding-right: 2.5em;\n}\n\n.control.has-icons-right .icon.is-right {\n  right: 0;\n}\n\n.control.is-loading::after {\n  position: absolute !important;\n  right: 0.625em;\n  top: 0.625em;\n  z-index: 4;\n}\n\n.control.is-loading.is-small:after {\n  font-size: 0.75rem;\n}\n\n.control.is-loading.is-medium:after {\n  font-size: 1.25rem;\n}\n\n.control.is-loading.is-large:after {\n  font-size: 1.5rem;\n}\n\n/* Bulma Components */\n.breadcrumb {\n  font-size: 1rem;\n  white-space: nowrap;\n}\n\n.breadcrumb a {\n  align-items: center;\n  color: #485fc7;\n  display: flex;\n  justify-content: center;\n  padding: 0 0.75em;\n}\n\n.breadcrumb a:hover {\n  color: #363636;\n}\n\n.breadcrumb li {\n  align-items: center;\n  display: flex;\n}\n\n.breadcrumb li:first-child a {\n  padding-left: 0;\n}\n\n.breadcrumb li.is-active a {\n  color: #363636;\n  cursor: default;\n  pointer-events: none;\n}\n\n.breadcrumb li + li::before {\n  color: #b5b5b5;\n  content: \"\\0002f\";\n}\n\n.breadcrumb ul,\n.breadcrumb ol {\n  align-items: flex-start;\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n\n.breadcrumb .icon:first-child {\n  margin-right: 0.5em;\n}\n\n.breadcrumb .icon:last-child {\n  margin-left: 0.5em;\n}\n\n.breadcrumb.is-centered ol,\n.breadcrumb.is-centered ul {\n  justify-content: center;\n}\n\n.breadcrumb.is-right ol,\n.breadcrumb.is-right ul {\n  justify-content: flex-end;\n}\n\n.breadcrumb.is-small {\n  font-size: 0.75rem;\n}\n\n.breadcrumb.is-medium {\n  font-size: 1.25rem;\n}\n\n.breadcrumb.is-large {\n  font-size: 1.5rem;\n}\n\n.breadcrumb.has-arrow-separator li + li::before {\n  content: \"\\02192\";\n}\n\n.breadcrumb.has-bullet-separator li + li::before {\n  content: \"\\02022\";\n}\n\n.breadcrumb.has-dot-separator li + li::before {\n  content: \"\\000b7\";\n}\n\n.breadcrumb.has-succeeds-separator li + li::before {\n  content: \"\\0227B\";\n}\n\n.card {\n  background-color: white;\n  border-radius: 0.25rem;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  color: #4a4a4a;\n  max-width: 100%;\n  position: relative;\n}\n\n.card-header:first-child, .card-content:first-child, .card-footer:first-child {\n  border-top-left-radius: 0.25rem;\n  border-top-right-radius: 0.25rem;\n}\n\n.card-header:last-child, .card-content:last-child, .card-footer:last-child {\n  border-bottom-left-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n\n.card-header {\n  background-color: transparent;\n  align-items: stretch;\n  box-shadow: 0 0.125em 0.25em rgba(10, 10, 10, 0.1);\n  display: flex;\n}\n\n.card-header-title {\n  align-items: center;\n  color: #363636;\n  display: flex;\n  flex-grow: 1;\n  font-weight: 700;\n  padding: 0.75rem 1rem;\n}\n\n.card-header-title.is-centered {\n  justify-content: center;\n}\n\n.card-header-icon {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n  background: none;\n  border: none;\n  color: currentColor;\n  font-family: inherit;\n  font-size: 1em;\n  margin: 0;\n  padding: 0;\n  align-items: center;\n  cursor: pointer;\n  display: flex;\n  justify-content: center;\n  padding: 0.75rem 1rem;\n}\n\n.card-image {\n  display: block;\n  position: relative;\n}\n\n.card-image:first-child img {\n  border-top-left-radius: 0.25rem;\n  border-top-right-radius: 0.25rem;\n}\n\n.card-image:last-child img {\n  border-bottom-left-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n\n.card-content {\n  background-color: transparent;\n  padding: 1.5rem;\n}\n\n.card-footer {\n  background-color: transparent;\n  border-top: 1px solid #ededed;\n  align-items: stretch;\n  display: flex;\n}\n\n.card-footer-item {\n  align-items: center;\n  display: flex;\n  flex-basis: 0;\n  flex-grow: 1;\n  flex-shrink: 0;\n  justify-content: center;\n  padding: 0.75rem;\n}\n\n.card-footer-item:not(:last-child) {\n  border-right: 1px solid #ededed;\n}\n\n.card .media:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.dropdown {\n  display: inline-flex;\n  position: relative;\n  vertical-align: top;\n}\n\n.dropdown.is-active .dropdown-menu, .dropdown.is-hoverable:hover .dropdown-menu {\n  display: block;\n}\n\n.dropdown.is-right .dropdown-menu {\n  left: auto;\n  right: 0;\n}\n\n.dropdown.is-up .dropdown-menu {\n  bottom: 100%;\n  padding-bottom: 4px;\n  padding-top: initial;\n  top: auto;\n}\n\n.dropdown-menu {\n  display: none;\n  left: 0;\n  min-width: 12rem;\n  padding-top: 4px;\n  position: absolute;\n  top: 100%;\n  z-index: 20;\n}\n\n.dropdown-content {\n  background-color: white;\n  border-radius: 4px;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  padding-bottom: 0.5rem;\n  padding-top: 0.5rem;\n}\n\n.dropdown-item {\n  color: #4a4a4a;\n  display: block;\n  font-size: 0.875rem;\n  line-height: 1.5;\n  padding: 0.375rem 1rem;\n  position: relative;\n}\n\na.dropdown-item,\nbutton.dropdown-item {\n  padding-right: 3rem;\n  text-align: inherit;\n  white-space: nowrap;\n  width: 100%;\n}\n\na.dropdown-item:hover,\nbutton.dropdown-item:hover {\n  background-color: whitesmoke;\n  color: #0a0a0a;\n}\n\na.dropdown-item.is-active,\nbutton.dropdown-item.is-active {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.dropdown-divider {\n  background-color: #ededed;\n  border: none;\n  display: block;\n  height: 1px;\n  margin: 0.5rem 0;\n}\n\n.level {\n  align-items: center;\n  justify-content: space-between;\n}\n\n.level code {\n  border-radius: 4px;\n}\n\n.level img {\n  display: inline-block;\n  vertical-align: top;\n}\n\n.level.is-mobile {\n  display: flex;\n}\n\n.level.is-mobile .level-left,\n.level.is-mobile .level-right {\n  display: flex;\n}\n\n.level.is-mobile .level-left + .level-right {\n  margin-top: 0;\n}\n\n.level.is-mobile .level-item:not(:last-child) {\n  margin-bottom: 0;\n  margin-right: 0.75rem;\n}\n\n.level.is-mobile .level-item:not(.is-narrow) {\n  flex-grow: 1;\n}\n\n@media screen and (min-width: 769px), print {\n  .level {\n    display: flex;\n  }\n  .level > .level-item:not(.is-narrow) {\n    flex-grow: 1;\n  }\n}\n\n.level-item {\n  align-items: center;\n  display: flex;\n  flex-basis: auto;\n  flex-grow: 0;\n  flex-shrink: 0;\n  justify-content: center;\n}\n\n.level-item .title,\n.level-item .subtitle {\n  margin-bottom: 0;\n}\n\n@media screen and (max-width: 768px) {\n  .level-item:not(:last-child) {\n    margin-bottom: 0.75rem;\n  }\n}\n\n.level-left,\n.level-right {\n  flex-basis: auto;\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.level-left .level-item.is-flexible,\n.level-right .level-item.is-flexible {\n  flex-grow: 1;\n}\n\n@media screen and (min-width: 769px), print {\n  .level-left .level-item:not(:last-child),\n  .level-right .level-item:not(:last-child) {\n    margin-right: 0.75rem;\n  }\n}\n\n.level-left {\n  align-items: center;\n  justify-content: flex-start;\n}\n\n@media screen and (max-width: 768px) {\n  .level-left + .level-right {\n    margin-top: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .level-left {\n    display: flex;\n  }\n}\n\n.level-right {\n  align-items: center;\n  justify-content: flex-end;\n}\n\n@media screen and (min-width: 769px), print {\n  .level-right {\n    display: flex;\n  }\n}\n\n.media {\n  align-items: flex-start;\n  display: flex;\n  text-align: inherit;\n}\n\n.media .content:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.media .media {\n  border-top: 1px solid rgba(219, 219, 219, 0.5);\n  display: flex;\n  padding-top: 0.75rem;\n}\n\n.media .media .content:not(:last-child),\n.media .media .control:not(:last-child) {\n  margin-bottom: 0.5rem;\n}\n\n.media .media .media {\n  padding-top: 0.5rem;\n}\n\n.media .media .media + .media {\n  margin-top: 0.5rem;\n}\n\n.media + .media {\n  border-top: 1px solid rgba(219, 219, 219, 0.5);\n  margin-top: 1rem;\n  padding-top: 1rem;\n}\n\n.media.is-large + .media {\n  margin-top: 1.5rem;\n  padding-top: 1.5rem;\n}\n\n.media-left,\n.media-right {\n  flex-basis: auto;\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.media-left {\n  margin-right: 1rem;\n}\n\n.media-right {\n  margin-left: 1rem;\n}\n\n.media-content {\n  flex-basis: auto;\n  flex-grow: 1;\n  flex-shrink: 1;\n  text-align: inherit;\n}\n\n@media screen and (max-width: 768px) {\n  .media-content {\n    overflow-x: auto;\n  }\n}\n\n.menu {\n  font-size: 1rem;\n}\n\n.menu.is-small {\n  font-size: 0.75rem;\n}\n\n.menu.is-medium {\n  font-size: 1.25rem;\n}\n\n.menu.is-large {\n  font-size: 1.5rem;\n}\n\n.menu-list {\n  line-height: 1.25;\n}\n\n.menu-list a {\n  border-radius: 2px;\n  color: #4a4a4a;\n  display: block;\n  padding: 0.5em 0.75em;\n}\n\n.menu-list a:hover {\n  background-color: whitesmoke;\n  color: #363636;\n}\n\n.menu-list a.is-active {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.menu-list li ul {\n  border-left: 1px solid #dbdbdb;\n  margin: 0.75em;\n  padding-left: 0.75em;\n}\n\n.menu-label {\n  color: #7a7a7a;\n  font-size: 0.75em;\n  letter-spacing: 0.1em;\n  text-transform: uppercase;\n}\n\n.menu-label:not(:first-child) {\n  margin-top: 1em;\n}\n\n.menu-label:not(:last-child) {\n  margin-bottom: 1em;\n}\n\n.message {\n  background-color: whitesmoke;\n  border-radius: 4px;\n  font-size: 1rem;\n}\n\n.message strong {\n  color: currentColor;\n}\n\n.message a:not(.button):not(.tag):not(.dropdown-item) {\n  color: currentColor;\n  text-decoration: underline;\n}\n\n.message.is-small {\n  font-size: 0.75rem;\n}\n\n.message.is-medium {\n  font-size: 1.25rem;\n}\n\n.message.is-large {\n  font-size: 1.5rem;\n}\n\n.message.is-white {\n  background-color: white;\n}\n\n.message.is-white .message-header {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.message.is-white .message-body {\n  border-color: white;\n}\n\n.message.is-black {\n  background-color: #fafafa;\n}\n\n.message.is-black .message-header {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.message.is-black .message-body {\n  border-color: #0a0a0a;\n}\n\n.message.is-light {\n  background-color: #fafafa;\n}\n\n.message.is-light .message-header {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.message.is-light .message-body {\n  border-color: whitesmoke;\n}\n\n.message.is-dark {\n  background-color: #fafafa;\n}\n\n.message.is-dark .message-header {\n  background-color: #363636;\n  color: #fff;\n}\n\n.message.is-dark .message-body {\n  border-color: #363636;\n}\n\n.message.is-primary {\n  background-color: #ebfffc;\n}\n\n.message.is-primary .message-header {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.message.is-primary .message-body {\n  border-color: #00d1b2;\n  color: #00947e;\n}\n\n.message.is-link {\n  background-color: #eff1fa;\n}\n\n.message.is-link .message-header {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.message.is-link .message-body {\n  border-color: #485fc7;\n  color: #3850b7;\n}\n\n.message.is-info {\n  background-color: #eff5fb;\n}\n\n.message.is-info .message-header {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.message.is-info .message-body {\n  border-color: #3e8ed0;\n  color: #296fa8;\n}\n\n.message.is-success {\n  background-color: #effaf5;\n}\n\n.message.is-success .message-header {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.message.is-success .message-body {\n  border-color: #48c78e;\n  color: #257953;\n}\n\n.message.is-warning {\n  background-color: #fffaeb;\n}\n\n.message.is-warning .message-header {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.message.is-warning .message-body {\n  border-color: #ffe08a;\n  color: #946c00;\n}\n\n.message.is-danger {\n  background-color: #feecf0;\n}\n\n.message.is-danger .message-header {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.message.is-danger .message-body {\n  border-color: #f14668;\n  color: #cc0f35;\n}\n\n.message-header {\n  align-items: center;\n  background-color: #4a4a4a;\n  border-radius: 4px 4px 0 0;\n  color: #fff;\n  display: flex;\n  font-weight: 700;\n  justify-content: space-between;\n  line-height: 1.25;\n  padding: 0.75em 1em;\n  position: relative;\n}\n\n.message-header .delete {\n  flex-grow: 0;\n  flex-shrink: 0;\n  margin-left: 0.75em;\n}\n\n.message-header + .message-body {\n  border-width: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.message-body {\n  border-color: #dbdbdb;\n  border-radius: 4px;\n  border-style: solid;\n  border-width: 0 0 0 4px;\n  color: #4a4a4a;\n  padding: 1.25em 1.5em;\n}\n\n.message-body code,\n.message-body pre {\n  background-color: white;\n}\n\n.message-body pre code {\n  background-color: transparent;\n}\n\n.modal {\n  align-items: center;\n  display: none;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  position: fixed;\n  z-index: 40;\n}\n\n.modal.is-active {\n  display: flex;\n}\n\n.modal-background {\n  background-color: rgba(10, 10, 10, 0.86);\n}\n\n.modal-content,\n.modal-card {\n  margin: 0 20px;\n  max-height: calc(100vh - 160px);\n  overflow: auto;\n  position: relative;\n  width: 100%;\n}\n\n@media screen and (min-width: 769px) {\n  .modal-content,\n  .modal-card {\n    margin: 0 auto;\n    max-height: calc(100vh - 40px);\n    width: 640px;\n  }\n}\n\n.modal-close {\n  background: none;\n  height: 40px;\n  position: fixed;\n  right: 20px;\n  top: 20px;\n  width: 40px;\n}\n\n.modal-card {\n  display: flex;\n  flex-direction: column;\n  max-height: calc(100vh - 40px);\n  overflow: hidden;\n  -ms-overflow-y: visible;\n}\n\n.modal-card-head,\n.modal-card-foot {\n  align-items: center;\n  background-color: whitesmoke;\n  display: flex;\n  flex-shrink: 0;\n  justify-content: flex-start;\n  padding: 20px;\n  position: relative;\n}\n\n.modal-card-head {\n  border-bottom: 1px solid #dbdbdb;\n  border-top-left-radius: 6px;\n  border-top-right-radius: 6px;\n}\n\n.modal-card-title {\n  color: #363636;\n  flex-grow: 1;\n  flex-shrink: 0;\n  font-size: 1.5rem;\n  line-height: 1;\n}\n\n.modal-card-foot {\n  border-bottom-left-radius: 6px;\n  border-bottom-right-radius: 6px;\n  border-top: 1px solid #dbdbdb;\n}\n\n.modal-card-foot .button:not(:last-child) {\n  margin-right: 0.5em;\n}\n\n.modal-card-body {\n  -webkit-overflow-scrolling: touch;\n  background-color: white;\n  flex-grow: 1;\n  flex-shrink: 1;\n  overflow: auto;\n  padding: 20px;\n}\n\n.navbar {\n  background-color: white;\n  min-height: 3.25rem;\n  position: relative;\n  z-index: 30;\n}\n\n.navbar.is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-brand > .navbar-item,\n.navbar.is-white .navbar-brand .navbar-link {\n  color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-brand > a.navbar-item:focus, .navbar.is-white .navbar-brand > a.navbar-item:hover, .navbar.is-white .navbar-brand > a.navbar-item.is-active,\n.navbar.is-white .navbar-brand .navbar-link:focus,\n.navbar.is-white .navbar-brand .navbar-link:hover,\n.navbar.is-white .navbar-brand .navbar-link.is-active {\n  background-color: #f2f2f2;\n  color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-brand .navbar-link::after {\n  border-color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-burger {\n  color: #0a0a0a;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-white .navbar-start > .navbar-item,\n  .navbar.is-white .navbar-start .navbar-link,\n  .navbar.is-white .navbar-end > .navbar-item,\n  .navbar.is-white .navbar-end .navbar-link {\n    color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-start > a.navbar-item:focus, .navbar.is-white .navbar-start > a.navbar-item:hover, .navbar.is-white .navbar-start > a.navbar-item.is-active,\n  .navbar.is-white .navbar-start .navbar-link:focus,\n  .navbar.is-white .navbar-start .navbar-link:hover,\n  .navbar.is-white .navbar-start .navbar-link.is-active,\n  .navbar.is-white .navbar-end > a.navbar-item:focus,\n  .navbar.is-white .navbar-end > a.navbar-item:hover,\n  .navbar.is-white .navbar-end > a.navbar-item.is-active,\n  .navbar.is-white .navbar-end .navbar-link:focus,\n  .navbar.is-white .navbar-end .navbar-link:hover,\n  .navbar.is-white .navbar-end .navbar-link.is-active {\n    background-color: #f2f2f2;\n    color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-start .navbar-link::after,\n  .navbar.is-white .navbar-end .navbar-link::after {\n    border-color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #f2f2f2;\n    color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-dropdown a.navbar-item.is-active {\n    background-color: white;\n    color: #0a0a0a;\n  }\n}\n\n.navbar.is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.navbar.is-black .navbar-brand > .navbar-item,\n.navbar.is-black .navbar-brand .navbar-link {\n  color: white;\n}\n\n.navbar.is-black .navbar-brand > a.navbar-item:focus, .navbar.is-black .navbar-brand > a.navbar-item:hover, .navbar.is-black .navbar-brand > a.navbar-item.is-active,\n.navbar.is-black .navbar-brand .navbar-link:focus,\n.navbar.is-black .navbar-brand .navbar-link:hover,\n.navbar.is-black .navbar-brand .navbar-link.is-active {\n  background-color: black;\n  color: white;\n}\n\n.navbar.is-black .navbar-brand .navbar-link::after {\n  border-color: white;\n}\n\n.navbar.is-black .navbar-burger {\n  color: white;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-black .navbar-start > .navbar-item,\n  .navbar.is-black .navbar-start .navbar-link,\n  .navbar.is-black .navbar-end > .navbar-item,\n  .navbar.is-black .navbar-end .navbar-link {\n    color: white;\n  }\n  .navbar.is-black .navbar-start > a.navbar-item:focus, .navbar.is-black .navbar-start > a.navbar-item:hover, .navbar.is-black .navbar-start > a.navbar-item.is-active,\n  .navbar.is-black .navbar-start .navbar-link:focus,\n  .navbar.is-black .navbar-start .navbar-link:hover,\n  .navbar.is-black .navbar-start .navbar-link.is-active,\n  .navbar.is-black .navbar-end > a.navbar-item:focus,\n  .navbar.is-black .navbar-end > a.navbar-item:hover,\n  .navbar.is-black .navbar-end > a.navbar-item.is-active,\n  .navbar.is-black .navbar-end .navbar-link:focus,\n  .navbar.is-black .navbar-end .navbar-link:hover,\n  .navbar.is-black .navbar-end .navbar-link.is-active {\n    background-color: black;\n    color: white;\n  }\n  .navbar.is-black .navbar-start .navbar-link::after,\n  .navbar.is-black .navbar-end .navbar-link::after {\n    border-color: white;\n  }\n  .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: black;\n    color: white;\n  }\n  .navbar.is-black .navbar-dropdown a.navbar-item.is-active {\n    background-color: #0a0a0a;\n    color: white;\n  }\n}\n\n.navbar.is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-brand > .navbar-item,\n.navbar.is-light .navbar-brand .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-brand > a.navbar-item:focus, .navbar.is-light .navbar-brand > a.navbar-item:hover, .navbar.is-light .navbar-brand > a.navbar-item.is-active,\n.navbar.is-light .navbar-brand .navbar-link:focus,\n.navbar.is-light .navbar-brand .navbar-link:hover,\n.navbar.is-light .navbar-brand .navbar-link.is-active {\n  background-color: #e8e8e8;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-brand .navbar-link::after {\n  border-color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-burger {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-light .navbar-start > .navbar-item,\n  .navbar.is-light .navbar-start .navbar-link,\n  .navbar.is-light .navbar-end > .navbar-item,\n  .navbar.is-light .navbar-end .navbar-link {\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-start > a.navbar-item:focus, .navbar.is-light .navbar-start > a.navbar-item:hover, .navbar.is-light .navbar-start > a.navbar-item.is-active,\n  .navbar.is-light .navbar-start .navbar-link:focus,\n  .navbar.is-light .navbar-start .navbar-link:hover,\n  .navbar.is-light .navbar-start .navbar-link.is-active,\n  .navbar.is-light .navbar-end > a.navbar-item:focus,\n  .navbar.is-light .navbar-end > a.navbar-item:hover,\n  .navbar.is-light .navbar-end > a.navbar-item.is-active,\n  .navbar.is-light .navbar-end .navbar-link:focus,\n  .navbar.is-light .navbar-end .navbar-link:hover,\n  .navbar.is-light .navbar-end .navbar-link.is-active {\n    background-color: #e8e8e8;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-start .navbar-link::after,\n  .navbar.is-light .navbar-end .navbar-link::after {\n    border-color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #e8e8e8;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-dropdown a.navbar-item.is-active {\n    background-color: whitesmoke;\n    color: rgba(0, 0, 0, 0.7);\n  }\n}\n\n.navbar.is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.navbar.is-dark .navbar-brand > .navbar-item,\n.navbar.is-dark .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-dark .navbar-brand > a.navbar-item:focus, .navbar.is-dark .navbar-brand > a.navbar-item:hover, .navbar.is-dark .navbar-brand > a.navbar-item.is-active,\n.navbar.is-dark .navbar-brand .navbar-link:focus,\n.navbar.is-dark .navbar-brand .navbar-link:hover,\n.navbar.is-dark .navbar-brand .navbar-link.is-active {\n  background-color: #292929;\n  color: #fff;\n}\n\n.navbar.is-dark .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-dark .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-dark .navbar-start > .navbar-item,\n  .navbar.is-dark .navbar-start .navbar-link,\n  .navbar.is-dark .navbar-end > .navbar-item,\n  .navbar.is-dark .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-dark .navbar-start > a.navbar-item:focus, .navbar.is-dark .navbar-start > a.navbar-item:hover, .navbar.is-dark .navbar-start > a.navbar-item.is-active,\n  .navbar.is-dark .navbar-start .navbar-link:focus,\n  .navbar.is-dark .navbar-start .navbar-link:hover,\n  .navbar.is-dark .navbar-start .navbar-link.is-active,\n  .navbar.is-dark .navbar-end > a.navbar-item:focus,\n  .navbar.is-dark .navbar-end > a.navbar-item:hover,\n  .navbar.is-dark .navbar-end > a.navbar-item.is-active,\n  .navbar.is-dark .navbar-end .navbar-link:focus,\n  .navbar.is-dark .navbar-end .navbar-link:hover,\n  .navbar.is-dark .navbar-end .navbar-link.is-active {\n    background-color: #292929;\n    color: #fff;\n  }\n  .navbar.is-dark .navbar-start .navbar-link::after,\n  .navbar.is-dark .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #292929;\n    color: #fff;\n  }\n  .navbar.is-dark .navbar-dropdown a.navbar-item.is-active {\n    background-color: #363636;\n    color: #fff;\n  }\n}\n\n.navbar.is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.navbar.is-primary .navbar-brand > .navbar-item,\n.navbar.is-primary .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-primary .navbar-brand > a.navbar-item:focus, .navbar.is-primary .navbar-brand > a.navbar-item:hover, .navbar.is-primary .navbar-brand > a.navbar-item.is-active,\n.navbar.is-primary .navbar-brand .navbar-link:focus,\n.navbar.is-primary .navbar-brand .navbar-link:hover,\n.navbar.is-primary .navbar-brand .navbar-link.is-active {\n  background-color: #00b89c;\n  color: #fff;\n}\n\n.navbar.is-primary .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-primary .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-primary .navbar-start > .navbar-item,\n  .navbar.is-primary .navbar-start .navbar-link,\n  .navbar.is-primary .navbar-end > .navbar-item,\n  .navbar.is-primary .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-primary .navbar-start > a.navbar-item:focus, .navbar.is-primary .navbar-start > a.navbar-item:hover, .navbar.is-primary .navbar-start > a.navbar-item.is-active,\n  .navbar.is-primary .navbar-start .navbar-link:focus,\n  .navbar.is-primary .navbar-start .navbar-link:hover,\n  .navbar.is-primary .navbar-start .navbar-link.is-active,\n  .navbar.is-primary .navbar-end > a.navbar-item:focus,\n  .navbar.is-primary .navbar-end > a.navbar-item:hover,\n  .navbar.is-primary .navbar-end > a.navbar-item.is-active,\n  .navbar.is-primary .navbar-end .navbar-link:focus,\n  .navbar.is-primary .navbar-end .navbar-link:hover,\n  .navbar.is-primary .navbar-end .navbar-link.is-active {\n    background-color: #00b89c;\n    color: #fff;\n  }\n  .navbar.is-primary .navbar-start .navbar-link::after,\n  .navbar.is-primary .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #00b89c;\n    color: #fff;\n  }\n  .navbar.is-primary .navbar-dropdown a.navbar-item.is-active {\n    background-color: #00d1b2;\n    color: #fff;\n  }\n}\n\n.navbar.is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.navbar.is-link .navbar-brand > .navbar-item,\n.navbar.is-link .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-link .navbar-brand > a.navbar-item:focus, .navbar.is-link .navbar-brand > a.navbar-item:hover, .navbar.is-link .navbar-brand > a.navbar-item.is-active,\n.navbar.is-link .navbar-brand .navbar-link:focus,\n.navbar.is-link .navbar-brand .navbar-link:hover,\n.navbar.is-link .navbar-brand .navbar-link.is-active {\n  background-color: #3a51bb;\n  color: #fff;\n}\n\n.navbar.is-link .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-link .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-link .navbar-start > .navbar-item,\n  .navbar.is-link .navbar-start .navbar-link,\n  .navbar.is-link .navbar-end > .navbar-item,\n  .navbar.is-link .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-link .navbar-start > a.navbar-item:focus, .navbar.is-link .navbar-start > a.navbar-item:hover, .navbar.is-link .navbar-start > a.navbar-item.is-active,\n  .navbar.is-link .navbar-start .navbar-link:focus,\n  .navbar.is-link .navbar-start .navbar-link:hover,\n  .navbar.is-link .navbar-start .navbar-link.is-active,\n  .navbar.is-link .navbar-end > a.navbar-item:focus,\n  .navbar.is-link .navbar-end > a.navbar-item:hover,\n  .navbar.is-link .navbar-end > a.navbar-item.is-active,\n  .navbar.is-link .navbar-end .navbar-link:focus,\n  .navbar.is-link .navbar-end .navbar-link:hover,\n  .navbar.is-link .navbar-end .navbar-link.is-active {\n    background-color: #3a51bb;\n    color: #fff;\n  }\n  .navbar.is-link .navbar-start .navbar-link::after,\n  .navbar.is-link .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #3a51bb;\n    color: #fff;\n  }\n  .navbar.is-link .navbar-dropdown a.navbar-item.is-active {\n    background-color: #485fc7;\n    color: #fff;\n  }\n}\n\n.navbar.is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.navbar.is-info .navbar-brand > .navbar-item,\n.navbar.is-info .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-info .navbar-brand > a.navbar-item:focus, .navbar.is-info .navbar-brand > a.navbar-item:hover, .navbar.is-info .navbar-brand > a.navbar-item.is-active,\n.navbar.is-info .navbar-brand .navbar-link:focus,\n.navbar.is-info .navbar-brand .navbar-link:hover,\n.navbar.is-info .navbar-brand .navbar-link.is-active {\n  background-color: #3082c5;\n  color: #fff;\n}\n\n.navbar.is-info .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-info .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-info .navbar-start > .navbar-item,\n  .navbar.is-info .navbar-start .navbar-link,\n  .navbar.is-info .navbar-end > .navbar-item,\n  .navbar.is-info .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-info .navbar-start > a.navbar-item:focus, .navbar.is-info .navbar-start > a.navbar-item:hover, .navbar.is-info .navbar-start > a.navbar-item.is-active,\n  .navbar.is-info .navbar-start .navbar-link:focus,\n  .navbar.is-info .navbar-start .navbar-link:hover,\n  .navbar.is-info .navbar-start .navbar-link.is-active,\n  .navbar.is-info .navbar-end > a.navbar-item:focus,\n  .navbar.is-info .navbar-end > a.navbar-item:hover,\n  .navbar.is-info .navbar-end > a.navbar-item.is-active,\n  .navbar.is-info .navbar-end .navbar-link:focus,\n  .navbar.is-info .navbar-end .navbar-link:hover,\n  .navbar.is-info .navbar-end .navbar-link.is-active {\n    background-color: #3082c5;\n    color: #fff;\n  }\n  .navbar.is-info .navbar-start .navbar-link::after,\n  .navbar.is-info .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #3082c5;\n    color: #fff;\n  }\n  .navbar.is-info .navbar-dropdown a.navbar-item.is-active {\n    background-color: #3e8ed0;\n    color: #fff;\n  }\n}\n\n.navbar.is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.navbar.is-success .navbar-brand > .navbar-item,\n.navbar.is-success .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-success .navbar-brand > a.navbar-item:focus, .navbar.is-success .navbar-brand > a.navbar-item:hover, .navbar.is-success .navbar-brand > a.navbar-item.is-active,\n.navbar.is-success .navbar-brand .navbar-link:focus,\n.navbar.is-success .navbar-brand .navbar-link:hover,\n.navbar.is-success .navbar-brand .navbar-link.is-active {\n  background-color: #3abb81;\n  color: #fff;\n}\n\n.navbar.is-success .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-success .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-success .navbar-start > .navbar-item,\n  .navbar.is-success .navbar-start .navbar-link,\n  .navbar.is-success .navbar-end > .navbar-item,\n  .navbar.is-success .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-success .navbar-start > a.navbar-item:focus, .navbar.is-success .navbar-start > a.navbar-item:hover, .navbar.is-success .navbar-start > a.navbar-item.is-active,\n  .navbar.is-success .navbar-start .navbar-link:focus,\n  .navbar.is-success .navbar-start .navbar-link:hover,\n  .navbar.is-success .navbar-start .navbar-link.is-active,\n  .navbar.is-success .navbar-end > a.navbar-item:focus,\n  .navbar.is-success .navbar-end > a.navbar-item:hover,\n  .navbar.is-success .navbar-end > a.navbar-item.is-active,\n  .navbar.is-success .navbar-end .navbar-link:focus,\n  .navbar.is-success .navbar-end .navbar-link:hover,\n  .navbar.is-success .navbar-end .navbar-link.is-active {\n    background-color: #3abb81;\n    color: #fff;\n  }\n  .navbar.is-success .navbar-start .navbar-link::after,\n  .navbar.is-success .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #3abb81;\n    color: #fff;\n  }\n  .navbar.is-success .navbar-dropdown a.navbar-item.is-active {\n    background-color: #48c78e;\n    color: #fff;\n  }\n}\n\n.navbar.is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-brand > .navbar-item,\n.navbar.is-warning .navbar-brand .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-brand > a.navbar-item:focus, .navbar.is-warning .navbar-brand > a.navbar-item:hover, .navbar.is-warning .navbar-brand > a.navbar-item.is-active,\n.navbar.is-warning .navbar-brand .navbar-link:focus,\n.navbar.is-warning .navbar-brand .navbar-link:hover,\n.navbar.is-warning .navbar-brand .navbar-link.is-active {\n  background-color: #ffd970;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-brand .navbar-link::after {\n  border-color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-burger {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-warning .navbar-start > .navbar-item,\n  .navbar.is-warning .navbar-start .navbar-link,\n  .navbar.is-warning .navbar-end > .navbar-item,\n  .navbar.is-warning .navbar-end .navbar-link {\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-start > a.navbar-item:focus, .navbar.is-warning .navbar-start > a.navbar-item:hover, .navbar.is-warning .navbar-start > a.navbar-item.is-active,\n  .navbar.is-warning .navbar-start .navbar-link:focus,\n  .navbar.is-warning .navbar-start .navbar-link:hover,\n  .navbar.is-warning .navbar-start .navbar-link.is-active,\n  .navbar.is-warning .navbar-end > a.navbar-item:focus,\n  .navbar.is-warning .navbar-end > a.navbar-item:hover,\n  .navbar.is-warning .navbar-end > a.navbar-item.is-active,\n  .navbar.is-warning .navbar-end .navbar-link:focus,\n  .navbar.is-warning .navbar-end .navbar-link:hover,\n  .navbar.is-warning .navbar-end .navbar-link.is-active {\n    background-color: #ffd970;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-start .navbar-link::after,\n  .navbar.is-warning .navbar-end .navbar-link::after {\n    border-color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #ffd970;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-dropdown a.navbar-item.is-active {\n    background-color: #ffe08a;\n    color: rgba(0, 0, 0, 0.7);\n  }\n}\n\n.navbar.is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.navbar.is-danger .navbar-brand > .navbar-item,\n.navbar.is-danger .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-danger .navbar-brand > a.navbar-item:focus, .navbar.is-danger .navbar-brand > a.navbar-item:hover, .navbar.is-danger .navbar-brand > a.navbar-item.is-active,\n.navbar.is-danger .navbar-brand .navbar-link:focus,\n.navbar.is-danger .navbar-brand .navbar-link:hover,\n.navbar.is-danger .navbar-brand .navbar-link.is-active {\n  background-color: #ef2e55;\n  color: #fff;\n}\n\n.navbar.is-danger .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-danger .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-danger .navbar-start > .navbar-item,\n  .navbar.is-danger .navbar-start .navbar-link,\n  .navbar.is-danger .navbar-end > .navbar-item,\n  .navbar.is-danger .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-danger .navbar-start > a.navbar-item:focus, .navbar.is-danger .navbar-start > a.navbar-item:hover, .navbar.is-danger .navbar-start > a.navbar-item.is-active,\n  .navbar.is-danger .navbar-start .navbar-link:focus,\n  .navbar.is-danger .navbar-start .navbar-link:hover,\n  .navbar.is-danger .navbar-start .navbar-link.is-active,\n  .navbar.is-danger .navbar-end > a.navbar-item:focus,\n  .navbar.is-danger .navbar-end > a.navbar-item:hover,\n  .navbar.is-danger .navbar-end > a.navbar-item.is-active,\n  .navbar.is-danger .navbar-end .navbar-link:focus,\n  .navbar.is-danger .navbar-end .navbar-link:hover,\n  .navbar.is-danger .navbar-end .navbar-link.is-active {\n    background-color: #ef2e55;\n    color: #fff;\n  }\n  .navbar.is-danger .navbar-start .navbar-link::after,\n  .navbar.is-danger .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #ef2e55;\n    color: #fff;\n  }\n  .navbar.is-danger .navbar-dropdown a.navbar-item.is-active {\n    background-color: #f14668;\n    color: #fff;\n  }\n}\n\n.navbar > .container {\n  align-items: stretch;\n  display: flex;\n  min-height: 3.25rem;\n  width: 100%;\n}\n\n.navbar.has-shadow {\n  box-shadow: 0 2px 0 0 whitesmoke;\n}\n\n.navbar.is-fixed-bottom, .navbar.is-fixed-top {\n  left: 0;\n  position: fixed;\n  right: 0;\n  z-index: 30;\n}\n\n.navbar.is-fixed-bottom {\n  bottom: 0;\n}\n\n.navbar.is-fixed-bottom.has-shadow {\n  box-shadow: 0 -2px 0 0 whitesmoke;\n}\n\n.navbar.is-fixed-top {\n  top: 0;\n}\n\nhtml.has-navbar-fixed-top,\nbody.has-navbar-fixed-top {\n  padding-top: 3.25rem;\n}\n\nhtml.has-navbar-fixed-bottom,\nbody.has-navbar-fixed-bottom {\n  padding-bottom: 3.25rem;\n}\n\n.navbar-brand,\n.navbar-tabs {\n  align-items: stretch;\n  display: flex;\n  flex-shrink: 0;\n  min-height: 3.25rem;\n}\n\n.navbar-brand a.navbar-item:focus, .navbar-brand a.navbar-item:hover {\n  background-color: transparent;\n}\n\n.navbar-tabs {\n  -webkit-overflow-scrolling: touch;\n  max-width: 100vw;\n  overflow-x: auto;\n  overflow-y: hidden;\n}\n\n.navbar-burger {\n  color: #4a4a4a;\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n  background: none;\n  border: none;\n  cursor: pointer;\n  display: block;\n  height: 3.25rem;\n  position: relative;\n  width: 3.25rem;\n  margin-left: auto;\n}\n\n.navbar-burger span {\n  background-color: currentColor;\n  display: block;\n  height: 1px;\n  left: calc(50% - 8px);\n  position: absolute;\n  transform-origin: center;\n  transition-duration: 86ms;\n  transition-property: background-color, opacity, transform;\n  transition-timing-function: ease-out;\n  width: 16px;\n}\n\n.navbar-burger span:nth-child(1) {\n  top: calc(50% - 6px);\n}\n\n.navbar-burger span:nth-child(2) {\n  top: calc(50% - 1px);\n}\n\n.navbar-burger span:nth-child(3) {\n  top: calc(50% + 4px);\n}\n\n.navbar-burger:hover {\n  background-color: rgba(0, 0, 0, 0.05);\n}\n\n.navbar-burger.is-active span:nth-child(1) {\n  transform: translateY(5px) rotate(45deg);\n}\n\n.navbar-burger.is-active span:nth-child(2) {\n  opacity: 0;\n}\n\n.navbar-burger.is-active span:nth-child(3) {\n  transform: translateY(-5px) rotate(-45deg);\n}\n\n.navbar-menu {\n  display: none;\n}\n\n.navbar-item,\n.navbar-link {\n  color: #4a4a4a;\n  display: block;\n  line-height: 1.5;\n  padding: 0.5rem 0.75rem;\n  position: relative;\n}\n\n.navbar-item .icon:only-child,\n.navbar-link .icon:only-child {\n  margin-left: -0.25rem;\n  margin-right: -0.25rem;\n}\n\na.navbar-item,\n.navbar-link {\n  cursor: pointer;\n}\n\na.navbar-item:focus, a.navbar-item:focus-within, a.navbar-item:hover, a.navbar-item.is-active,\n.navbar-link:focus,\n.navbar-link:focus-within,\n.navbar-link:hover,\n.navbar-link.is-active {\n  background-color: #fafafa;\n  color: #485fc7;\n}\n\n.navbar-item {\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.navbar-item img {\n  max-height: 1.75rem;\n}\n\n.navbar-item.has-dropdown {\n  padding: 0;\n}\n\n.navbar-item.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.navbar-item.is-tab {\n  border-bottom: 1px solid transparent;\n  min-height: 3.25rem;\n  padding-bottom: calc(0.5rem - 1px);\n}\n\n.navbar-item.is-tab:focus, .navbar-item.is-tab:hover {\n  background-color: transparent;\n  border-bottom-color: #485fc7;\n}\n\n.navbar-item.is-tab.is-active {\n  background-color: transparent;\n  border-bottom-color: #485fc7;\n  border-bottom-style: solid;\n  border-bottom-width: 3px;\n  color: #485fc7;\n  padding-bottom: calc(0.5rem - 3px);\n}\n\n.navbar-content {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.navbar-link:not(.is-arrowless) {\n  padding-right: 2.5em;\n}\n\n.navbar-link:not(.is-arrowless)::after {\n  border-color: #485fc7;\n  margin-top: -0.375em;\n  right: 1.125em;\n}\n\n.navbar-dropdown {\n  font-size: 0.875rem;\n  padding-bottom: 0.5rem;\n  padding-top: 0.5rem;\n}\n\n.navbar-dropdown .navbar-item {\n  padding-left: 1.5rem;\n  padding-right: 1.5rem;\n}\n\n.navbar-divider {\n  background-color: whitesmoke;\n  border: none;\n  display: none;\n  height: 2px;\n  margin: 0.5rem 0;\n}\n\n@media screen and (max-width: 1023px) {\n  .navbar > .container {\n    display: block;\n  }\n  .navbar-brand .navbar-item,\n  .navbar-tabs .navbar-item {\n    align-items: center;\n    display: flex;\n  }\n  .navbar-link::after {\n    display: none;\n  }\n  .navbar-menu {\n    background-color: white;\n    box-shadow: 0 8px 16px rgba(10, 10, 10, 0.1);\n    padding: 0.5rem 0;\n  }\n  .navbar-menu.is-active {\n    display: block;\n  }\n  .navbar.is-fixed-bottom-touch, .navbar.is-fixed-top-touch {\n    left: 0;\n    position: fixed;\n    right: 0;\n    z-index: 30;\n  }\n  .navbar.is-fixed-bottom-touch {\n    bottom: 0;\n  }\n  .navbar.is-fixed-bottom-touch.has-shadow {\n    box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1);\n  }\n  .navbar.is-fixed-top-touch {\n    top: 0;\n  }\n  .navbar.is-fixed-top .navbar-menu, .navbar.is-fixed-top-touch .navbar-menu {\n    -webkit-overflow-scrolling: touch;\n    max-height: calc(100vh - 3.25rem);\n    overflow: auto;\n  }\n  html.has-navbar-fixed-top-touch,\n  body.has-navbar-fixed-top-touch {\n    padding-top: 3.25rem;\n  }\n  html.has-navbar-fixed-bottom-touch,\n  body.has-navbar-fixed-bottom-touch {\n    padding-bottom: 3.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar,\n  .navbar-menu,\n  .navbar-start,\n  .navbar-end {\n    align-items: stretch;\n    display: flex;\n  }\n  .navbar {\n    min-height: 3.25rem;\n  }\n  .navbar.is-spaced {\n    padding: 1rem 2rem;\n  }\n  .navbar.is-spaced .navbar-start,\n  .navbar.is-spaced .navbar-end {\n    align-items: center;\n  }\n  .navbar.is-spaced a.navbar-item,\n  .navbar.is-spaced .navbar-link {\n    border-radius: 4px;\n  }\n  .navbar.is-transparent a.navbar-item:focus, .navbar.is-transparent a.navbar-item:hover, .navbar.is-transparent a.navbar-item.is-active,\n  .navbar.is-transparent .navbar-link:focus,\n  .navbar.is-transparent .navbar-link:hover,\n  .navbar.is-transparent .navbar-link.is-active {\n    background-color: transparent !important;\n  }\n  .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link {\n    background-color: transparent !important;\n  }\n  .navbar.is-transparent .navbar-dropdown a.navbar-item:focus, .navbar.is-transparent .navbar-dropdown a.navbar-item:hover {\n    background-color: whitesmoke;\n    color: #0a0a0a;\n  }\n  .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active {\n    background-color: whitesmoke;\n    color: #485fc7;\n  }\n  .navbar-burger {\n    display: none;\n  }\n  .navbar-item,\n  .navbar-link {\n    align-items: center;\n    display: flex;\n  }\n  .navbar-item.has-dropdown {\n    align-items: stretch;\n  }\n  .navbar-item.has-dropdown-up .navbar-link::after {\n    transform: rotate(135deg) translate(0.25em, -0.25em);\n  }\n  .navbar-item.has-dropdown-up .navbar-dropdown {\n    border-bottom: 2px solid #dbdbdb;\n    border-radius: 6px 6px 0 0;\n    border-top: none;\n    bottom: 100%;\n    box-shadow: 0 -8px 8px rgba(10, 10, 10, 0.1);\n    top: auto;\n  }\n  .navbar-item.is-active .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown {\n    display: block;\n  }\n  .navbar.is-spaced .navbar-item.is-active .navbar-dropdown, .navbar-item.is-active .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed {\n    opacity: 1;\n    pointer-events: auto;\n    transform: translateY(0);\n  }\n  .navbar-menu {\n    flex-grow: 1;\n    flex-shrink: 0;\n  }\n  .navbar-start {\n    justify-content: flex-start;\n    margin-right: auto;\n  }\n  .navbar-end {\n    justify-content: flex-end;\n    margin-left: auto;\n  }\n  .navbar-dropdown {\n    background-color: white;\n    border-bottom-left-radius: 6px;\n    border-bottom-right-radius: 6px;\n    border-top: 2px solid #dbdbdb;\n    box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1);\n    display: none;\n    font-size: 0.875rem;\n    left: 0;\n    min-width: 100%;\n    position: absolute;\n    top: 100%;\n    z-index: 20;\n  }\n  .navbar-dropdown .navbar-item {\n    padding: 0.375rem 1rem;\n    white-space: nowrap;\n  }\n  .navbar-dropdown a.navbar-item {\n    padding-right: 3rem;\n  }\n  .navbar-dropdown a.navbar-item:focus, .navbar-dropdown a.navbar-item:hover {\n    background-color: whitesmoke;\n    color: #0a0a0a;\n  }\n  .navbar-dropdown a.navbar-item.is-active {\n    background-color: whitesmoke;\n    color: #485fc7;\n  }\n  .navbar.is-spaced .navbar-dropdown, .navbar-dropdown.is-boxed {\n    border-radius: 6px;\n    border-top: none;\n    box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1);\n    display: block;\n    opacity: 0;\n    pointer-events: none;\n    top: calc(100% + (-4px));\n    transform: translateY(-5px);\n    transition-duration: 86ms;\n    transition-property: opacity, transform;\n  }\n  .navbar-dropdown.is-right {\n    left: auto;\n    right: 0;\n  }\n  .navbar-divider {\n    display: block;\n  }\n  .navbar > .container .navbar-brand,\n  .container > .navbar .navbar-brand {\n    margin-left: -0.75rem;\n  }\n  .navbar > .container .navbar-menu,\n  .container > .navbar .navbar-menu {\n    margin-right: -0.75rem;\n  }\n  .navbar.is-fixed-bottom-desktop, .navbar.is-fixed-top-desktop {\n    left: 0;\n    position: fixed;\n    right: 0;\n    z-index: 30;\n  }\n  .navbar.is-fixed-bottom-desktop {\n    bottom: 0;\n  }\n  .navbar.is-fixed-bottom-desktop.has-shadow {\n    box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1);\n  }\n  .navbar.is-fixed-top-desktop {\n    top: 0;\n  }\n  html.has-navbar-fixed-top-desktop,\n  body.has-navbar-fixed-top-desktop {\n    padding-top: 3.25rem;\n  }\n  html.has-navbar-fixed-bottom-desktop,\n  body.has-navbar-fixed-bottom-desktop {\n    padding-bottom: 3.25rem;\n  }\n  html.has-spaced-navbar-fixed-top,\n  body.has-spaced-navbar-fixed-top {\n    padding-top: 5.25rem;\n  }\n  html.has-spaced-navbar-fixed-bottom,\n  body.has-spaced-navbar-fixed-bottom {\n    padding-bottom: 5.25rem;\n  }\n  a.navbar-item.is-active,\n  .navbar-link.is-active {\n    color: #0a0a0a;\n  }\n  a.navbar-item.is-active:not(:focus):not(:hover),\n  .navbar-link.is-active:not(:focus):not(:hover) {\n    background-color: transparent;\n  }\n  .navbar-item.has-dropdown:focus .navbar-link, .navbar-item.has-dropdown:hover .navbar-link, .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #fafafa;\n  }\n}\n\n.hero.is-fullheight-with-navbar {\n  min-height: calc(100vh - 3.25rem);\n}\n\n.pagination {\n  font-size: 1rem;\n  margin: -0.25rem;\n}\n\n.pagination.is-small {\n  font-size: 0.75rem;\n}\n\n.pagination.is-medium {\n  font-size: 1.25rem;\n}\n\n.pagination.is-large {\n  font-size: 1.5rem;\n}\n\n.pagination.is-rounded .pagination-previous,\n.pagination.is-rounded .pagination-next {\n  padding-left: 1em;\n  padding-right: 1em;\n  border-radius: 9999px;\n}\n\n.pagination.is-rounded .pagination-link {\n  border-radius: 9999px;\n}\n\n.pagination,\n.pagination-list {\n  align-items: center;\n  display: flex;\n  justify-content: center;\n  text-align: center;\n}\n\n.pagination-previous,\n.pagination-next,\n.pagination-link,\n.pagination-ellipsis {\n  font-size: 1em;\n  justify-content: center;\n  margin: 0.25rem;\n  padding-left: 0.5em;\n  padding-right: 0.5em;\n  text-align: center;\n}\n\n.pagination-previous,\n.pagination-next,\n.pagination-link {\n  border-color: #dbdbdb;\n  color: #363636;\n  min-width: 2.5em;\n}\n\n.pagination-previous:hover,\n.pagination-next:hover,\n.pagination-link:hover {\n  border-color: #b5b5b5;\n  color: #363636;\n}\n\n.pagination-previous:focus,\n.pagination-next:focus,\n.pagination-link:focus {\n  border-color: #485fc7;\n}\n\n.pagination-previous:active,\n.pagination-next:active,\n.pagination-link:active {\n  box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2);\n}\n\n.pagination-previous[disabled], .pagination-previous.is-disabled,\n.pagination-next[disabled],\n.pagination-next.is-disabled,\n.pagination-link[disabled],\n.pagination-link.is-disabled {\n  background-color: #dbdbdb;\n  border-color: #dbdbdb;\n  box-shadow: none;\n  color: #7a7a7a;\n  opacity: 0.5;\n}\n\n.pagination-previous,\n.pagination-next {\n  padding-left: 0.75em;\n  padding-right: 0.75em;\n  white-space: nowrap;\n}\n\n.pagination-link.is-current {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n}\n\n.pagination-ellipsis {\n  color: #b5b5b5;\n  pointer-events: none;\n}\n\n.pagination-list {\n  flex-wrap: wrap;\n}\n\n.pagination-list li {\n  list-style: none;\n}\n\n@media screen and (max-width: 768px) {\n  .pagination {\n    flex-wrap: wrap;\n  }\n  .pagination-previous,\n  .pagination-next {\n    flex-grow: 1;\n    flex-shrink: 1;\n  }\n  .pagination-list li {\n    flex-grow: 1;\n    flex-shrink: 1;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .pagination-list {\n    flex-grow: 1;\n    flex-shrink: 1;\n    justify-content: flex-start;\n    order: 1;\n  }\n  .pagination-previous,\n  .pagination-next,\n  .pagination-link,\n  .pagination-ellipsis {\n    margin-bottom: 0;\n    margin-top: 0;\n  }\n  .pagination-previous {\n    order: 2;\n  }\n  .pagination-next {\n    order: 3;\n  }\n  .pagination {\n    justify-content: space-between;\n    margin-bottom: 0;\n    margin-top: 0;\n  }\n  .pagination.is-centered .pagination-previous {\n    order: 1;\n  }\n  .pagination.is-centered .pagination-list {\n    justify-content: center;\n    order: 2;\n  }\n  .pagination.is-centered .pagination-next {\n    order: 3;\n  }\n  .pagination.is-right .pagination-previous {\n    order: 1;\n  }\n  .pagination.is-right .pagination-next {\n    order: 2;\n  }\n  .pagination.is-right .pagination-list {\n    justify-content: flex-end;\n    order: 3;\n  }\n}\n\n.panel {\n  border-radius: 6px;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  font-size: 1rem;\n}\n\n.panel:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.panel.is-white .panel-heading {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.panel.is-white .panel-tabs a.is-active {\n  border-bottom-color: white;\n}\n\n.panel.is-white .panel-block.is-active .panel-icon {\n  color: white;\n}\n\n.panel.is-black .panel-heading {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.panel.is-black .panel-tabs a.is-active {\n  border-bottom-color: #0a0a0a;\n}\n\n.panel.is-black .panel-block.is-active .panel-icon {\n  color: #0a0a0a;\n}\n\n.panel.is-light .panel-heading {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.panel.is-light .panel-tabs a.is-active {\n  border-bottom-color: whitesmoke;\n}\n\n.panel.is-light .panel-block.is-active .panel-icon {\n  color: whitesmoke;\n}\n\n.panel.is-dark .panel-heading {\n  background-color: #363636;\n  color: #fff;\n}\n\n.panel.is-dark .panel-tabs a.is-active {\n  border-bottom-color: #363636;\n}\n\n.panel.is-dark .panel-block.is-active .panel-icon {\n  color: #363636;\n}\n\n.panel.is-primary .panel-heading {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.panel.is-primary .panel-tabs a.is-active {\n  border-bottom-color: #00d1b2;\n}\n\n.panel.is-primary .panel-block.is-active .panel-icon {\n  color: #00d1b2;\n}\n\n.panel.is-link .panel-heading {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.panel.is-link .panel-tabs a.is-active {\n  border-bottom-color: #485fc7;\n}\n\n.panel.is-link .panel-block.is-active .panel-icon {\n  color: #485fc7;\n}\n\n.panel.is-info .panel-heading {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.panel.is-info .panel-tabs a.is-active {\n  border-bottom-color: #3e8ed0;\n}\n\n.panel.is-info .panel-block.is-active .panel-icon {\n  color: #3e8ed0;\n}\n\n.panel.is-success .panel-heading {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.panel.is-success .panel-tabs a.is-active {\n  border-bottom-color: #48c78e;\n}\n\n.panel.is-success .panel-block.is-active .panel-icon {\n  color: #48c78e;\n}\n\n.panel.is-warning .panel-heading {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.panel.is-warning .panel-tabs a.is-active {\n  border-bottom-color: #ffe08a;\n}\n\n.panel.is-warning .panel-block.is-active .panel-icon {\n  color: #ffe08a;\n}\n\n.panel.is-danger .panel-heading {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.panel.is-danger .panel-tabs a.is-active {\n  border-bottom-color: #f14668;\n}\n\n.panel.is-danger .panel-block.is-active .panel-icon {\n  color: #f14668;\n}\n\n.panel-tabs:not(:last-child),\n.panel-block:not(:last-child) {\n  border-bottom: 1px solid #ededed;\n}\n\n.panel-heading {\n  background-color: #ededed;\n  border-radius: 6px 6px 0 0;\n  color: #363636;\n  font-size: 1.25em;\n  font-weight: 700;\n  line-height: 1.25;\n  padding: 0.75em 1em;\n}\n\n.panel-tabs {\n  align-items: flex-end;\n  display: flex;\n  font-size: 0.875em;\n  justify-content: center;\n}\n\n.panel-tabs a {\n  border-bottom: 1px solid #dbdbdb;\n  margin-bottom: -1px;\n  padding: 0.5em;\n}\n\n.panel-tabs a.is-active {\n  border-bottom-color: #4a4a4a;\n  color: #363636;\n}\n\n.panel-list a {\n  color: #4a4a4a;\n}\n\n.panel-list a:hover {\n  color: #485fc7;\n}\n\n.panel-block {\n  align-items: center;\n  color: #363636;\n  display: flex;\n  justify-content: flex-start;\n  padding: 0.5em 0.75em;\n}\n\n.panel-block input[type=\"checkbox\"] {\n  margin-right: 0.75em;\n}\n\n.panel-block > .control {\n  flex-grow: 1;\n  flex-shrink: 1;\n  width: 100%;\n}\n\n.panel-block.is-wrapped {\n  flex-wrap: wrap;\n}\n\n.panel-block.is-active {\n  border-left-color: #485fc7;\n  color: #363636;\n}\n\n.panel-block.is-active .panel-icon {\n  color: #485fc7;\n}\n\n.panel-block:last-child {\n  border-bottom-left-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\na.panel-block,\nlabel.panel-block {\n  cursor: pointer;\n}\n\na.panel-block:hover,\nlabel.panel-block:hover {\n  background-color: whitesmoke;\n}\n\n.panel-icon {\n  display: inline-block;\n  font-size: 14px;\n  height: 1em;\n  line-height: 1em;\n  text-align: center;\n  vertical-align: top;\n  width: 1em;\n  color: #7a7a7a;\n  margin-right: 0.75em;\n}\n\n.panel-icon .fa {\n  font-size: inherit;\n  line-height: inherit;\n}\n\n.tabs {\n  -webkit-overflow-scrolling: touch;\n  align-items: stretch;\n  display: flex;\n  font-size: 1rem;\n  justify-content: space-between;\n  overflow: hidden;\n  overflow-x: auto;\n  white-space: nowrap;\n}\n\n.tabs a {\n  align-items: center;\n  border-bottom-color: #dbdbdb;\n  border-bottom-style: solid;\n  border-bottom-width: 1px;\n  color: #4a4a4a;\n  display: flex;\n  justify-content: center;\n  margin-bottom: -1px;\n  padding: 0.5em 1em;\n  vertical-align: top;\n}\n\n.tabs a:hover {\n  border-bottom-color: #363636;\n  color: #363636;\n}\n\n.tabs li {\n  display: block;\n}\n\n.tabs li.is-active a {\n  border-bottom-color: #485fc7;\n  color: #485fc7;\n}\n\n.tabs ul {\n  align-items: center;\n  border-bottom-color: #dbdbdb;\n  border-bottom-style: solid;\n  border-bottom-width: 1px;\n  display: flex;\n  flex-grow: 1;\n  flex-shrink: 0;\n  justify-content: flex-start;\n}\n\n.tabs ul.is-left {\n  padding-right: 0.75em;\n}\n\n.tabs ul.is-center {\n  flex: none;\n  justify-content: center;\n  padding-left: 0.75em;\n  padding-right: 0.75em;\n}\n\n.tabs ul.is-right {\n  justify-content: flex-end;\n  padding-left: 0.75em;\n}\n\n.tabs .icon:first-child {\n  margin-right: 0.5em;\n}\n\n.tabs .icon:last-child {\n  margin-left: 0.5em;\n}\n\n.tabs.is-centered ul {\n  justify-content: center;\n}\n\n.tabs.is-right ul {\n  justify-content: flex-end;\n}\n\n.tabs.is-boxed a {\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n\n.tabs.is-boxed a:hover {\n  background-color: whitesmoke;\n  border-bottom-color: #dbdbdb;\n}\n\n.tabs.is-boxed li.is-active a {\n  background-color: white;\n  border-color: #dbdbdb;\n  border-bottom-color: transparent !important;\n}\n\n.tabs.is-fullwidth li {\n  flex-grow: 1;\n  flex-shrink: 0;\n}\n\n.tabs.is-toggle a {\n  border-color: #dbdbdb;\n  border-style: solid;\n  border-width: 1px;\n  margin-bottom: 0;\n  position: relative;\n}\n\n.tabs.is-toggle a:hover {\n  background-color: whitesmoke;\n  border-color: #b5b5b5;\n  z-index: 2;\n}\n\n.tabs.is-toggle li + li {\n  margin-left: -1px;\n}\n\n.tabs.is-toggle li:first-child a {\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n.tabs.is-toggle li:last-child a {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.tabs.is-toggle li.is-active a {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n  z-index: 1;\n}\n\n.tabs.is-toggle ul {\n  border-bottom: none;\n}\n\n.tabs.is-toggle.is-toggle-rounded li:first-child a {\n  border-bottom-left-radius: 9999px;\n  border-top-left-radius: 9999px;\n  padding-left: 1.25em;\n}\n\n.tabs.is-toggle.is-toggle-rounded li:last-child a {\n  border-bottom-right-radius: 9999px;\n  border-top-right-radius: 9999px;\n  padding-right: 1.25em;\n}\n\n.tabs.is-small {\n  font-size: 0.75rem;\n}\n\n.tabs.is-medium {\n  font-size: 1.25rem;\n}\n\n.tabs.is-large {\n  font-size: 1.5rem;\n}\n\n/* Bulma Grid */\n.column {\n  display: block;\n  flex-basis: 0;\n  flex-grow: 1;\n  flex-shrink: 1;\n  padding: 0.75rem;\n}\n\n.columns.is-mobile > .column.is-narrow {\n  flex: none;\n  width: unset;\n}\n\n.columns.is-mobile > .column.is-full {\n  flex: none;\n  width: 100%;\n}\n\n.columns.is-mobile > .column.is-three-quarters {\n  flex: none;\n  width: 75%;\n}\n\n.columns.is-mobile > .column.is-two-thirds {\n  flex: none;\n  width: 66.6666%;\n}\n\n.columns.is-mobile > .column.is-half {\n  flex: none;\n  width: 50%;\n}\n\n.columns.is-mobile > .column.is-one-third {\n  flex: none;\n  width: 33.3333%;\n}\n\n.columns.is-mobile > .column.is-one-quarter {\n  flex: none;\n  width: 25%;\n}\n\n.columns.is-mobile > .column.is-one-fifth {\n  flex: none;\n  width: 20%;\n}\n\n.columns.is-mobile > .column.is-two-fifths {\n  flex: none;\n  width: 40%;\n}\n\n.columns.is-mobile > .column.is-three-fifths {\n  flex: none;\n  width: 60%;\n}\n\n.columns.is-mobile > .column.is-four-fifths {\n  flex: none;\n  width: 80%;\n}\n\n.columns.is-mobile > .column.is-offset-three-quarters {\n  margin-left: 75%;\n}\n\n.columns.is-mobile > .column.is-offset-two-thirds {\n  margin-left: 66.6666%;\n}\n\n.columns.is-mobile > .column.is-offset-half {\n  margin-left: 50%;\n}\n\n.columns.is-mobile > .column.is-offset-one-third {\n  margin-left: 33.3333%;\n}\n\n.columns.is-mobile > .column.is-offset-one-quarter {\n  margin-left: 25%;\n}\n\n.columns.is-mobile > .column.is-offset-one-fifth {\n  margin-left: 20%;\n}\n\n.columns.is-mobile > .column.is-offset-two-fifths {\n  margin-left: 40%;\n}\n\n.columns.is-mobile > .column.is-offset-three-fifths {\n  margin-left: 60%;\n}\n\n.columns.is-mobile > .column.is-offset-four-fifths {\n  margin-left: 80%;\n}\n\n.columns.is-mobile > .column.is-0 {\n  flex: none;\n  width: 0%;\n}\n\n.columns.is-mobile > .column.is-offset-0 {\n  margin-left: 0%;\n}\n\n.columns.is-mobile > .column.is-1 {\n  flex: none;\n  width: 8.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-1 {\n  margin-left: 8.33333%;\n}\n\n.columns.is-mobile > .column.is-2 {\n  flex: none;\n  width: 16.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-2 {\n  margin-left: 16.66667%;\n}\n\n.columns.is-mobile > .column.is-3 {\n  flex: none;\n  width: 25%;\n}\n\n.columns.is-mobile > .column.is-offset-3 {\n  margin-left: 25%;\n}\n\n.columns.is-mobile > .column.is-4 {\n  flex: none;\n  width: 33.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-4 {\n  margin-left: 33.33333%;\n}\n\n.columns.is-mobile > .column.is-5 {\n  flex: none;\n  width: 41.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-5 {\n  margin-left: 41.66667%;\n}\n\n.columns.is-mobile > .column.is-6 {\n  flex: none;\n  width: 50%;\n}\n\n.columns.is-mobile > .column.is-offset-6 {\n  margin-left: 50%;\n}\n\n.columns.is-mobile > .column.is-7 {\n  flex: none;\n  width: 58.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-7 {\n  margin-left: 58.33333%;\n}\n\n.columns.is-mobile > .column.is-8 {\n  flex: none;\n  width: 66.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-8 {\n  margin-left: 66.66667%;\n}\n\n.columns.is-mobile > .column.is-9 {\n  flex: none;\n  width: 75%;\n}\n\n.columns.is-mobile > .column.is-offset-9 {\n  margin-left: 75%;\n}\n\n.columns.is-mobile > .column.is-10 {\n  flex: none;\n  width: 83.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-10 {\n  margin-left: 83.33333%;\n}\n\n.columns.is-mobile > .column.is-11 {\n  flex: none;\n  width: 91.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-11 {\n  margin-left: 91.66667%;\n}\n\n.columns.is-mobile > .column.is-12 {\n  flex: none;\n  width: 100%;\n}\n\n.columns.is-mobile > .column.is-offset-12 {\n  margin-left: 100%;\n}\n\n@media screen and (max-width: 768px) {\n  .column.is-narrow-mobile {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-mobile {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-mobile {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-mobile {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-mobile {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-mobile {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-mobile {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-mobile {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-mobile {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-mobile {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-mobile {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-mobile {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-mobile {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-mobile {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-mobile {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-mobile {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-mobile {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-mobile {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-mobile {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-mobile {\n    margin-left: 80%;\n  }\n  .column.is-0-mobile {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-mobile {\n    margin-left: 0%;\n  }\n  .column.is-1-mobile {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-mobile {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-mobile {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-mobile {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-mobile {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-mobile {\n    margin-left: 25%;\n  }\n  .column.is-4-mobile {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-mobile {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-mobile {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-mobile {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-mobile {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-mobile {\n    margin-left: 50%;\n  }\n  .column.is-7-mobile {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-mobile {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-mobile {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-mobile {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-mobile {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-mobile {\n    margin-left: 75%;\n  }\n  .column.is-10-mobile {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-mobile {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-mobile {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-mobile {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-mobile {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-mobile {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .column.is-narrow, .column.is-narrow-tablet {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full, .column.is-full-tablet {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters, .column.is-three-quarters-tablet {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds, .column.is-two-thirds-tablet {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half, .column.is-half-tablet {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third, .column.is-one-third-tablet {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter, .column.is-one-quarter-tablet {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth, .column.is-one-fifth-tablet {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths, .column.is-two-fifths-tablet {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths, .column.is-three-fifths-tablet {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths, .column.is-four-fifths-tablet {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters, .column.is-offset-three-quarters-tablet {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds, .column.is-offset-two-thirds-tablet {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half, .column.is-offset-half-tablet {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third, .column.is-offset-one-third-tablet {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter, .column.is-offset-one-quarter-tablet {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth, .column.is-offset-one-fifth-tablet {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths, .column.is-offset-two-fifths-tablet {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths, .column.is-offset-three-fifths-tablet {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths, .column.is-offset-four-fifths-tablet {\n    margin-left: 80%;\n  }\n  .column.is-0, .column.is-0-tablet {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0, .column.is-offset-0-tablet {\n    margin-left: 0%;\n  }\n  .column.is-1, .column.is-1-tablet {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1, .column.is-offset-1-tablet {\n    margin-left: 8.33333%;\n  }\n  .column.is-2, .column.is-2-tablet {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2, .column.is-offset-2-tablet {\n    margin-left: 16.66667%;\n  }\n  .column.is-3, .column.is-3-tablet {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3, .column.is-offset-3-tablet {\n    margin-left: 25%;\n  }\n  .column.is-4, .column.is-4-tablet {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4, .column.is-offset-4-tablet {\n    margin-left: 33.33333%;\n  }\n  .column.is-5, .column.is-5-tablet {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5, .column.is-offset-5-tablet {\n    margin-left: 41.66667%;\n  }\n  .column.is-6, .column.is-6-tablet {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6, .column.is-offset-6-tablet {\n    margin-left: 50%;\n  }\n  .column.is-7, .column.is-7-tablet {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7, .column.is-offset-7-tablet {\n    margin-left: 58.33333%;\n  }\n  .column.is-8, .column.is-8-tablet {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8, .column.is-offset-8-tablet {\n    margin-left: 66.66667%;\n  }\n  .column.is-9, .column.is-9-tablet {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9, .column.is-offset-9-tablet {\n    margin-left: 75%;\n  }\n  .column.is-10, .column.is-10-tablet {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10, .column.is-offset-10-tablet {\n    margin-left: 83.33333%;\n  }\n  .column.is-11, .column.is-11-tablet {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11, .column.is-offset-11-tablet {\n    margin-left: 91.66667%;\n  }\n  .column.is-12, .column.is-12-tablet {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12, .column.is-offset-12-tablet {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .column.is-narrow-touch {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-touch {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-touch {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-touch {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-touch {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-touch {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-touch {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-touch {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-touch {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-touch {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-touch {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-touch {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-touch {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-touch {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-touch {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-touch {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-touch {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-touch {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-touch {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-touch {\n    margin-left: 80%;\n  }\n  .column.is-0-touch {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-touch {\n    margin-left: 0%;\n  }\n  .column.is-1-touch {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-touch {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-touch {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-touch {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-touch {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-touch {\n    margin-left: 25%;\n  }\n  .column.is-4-touch {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-touch {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-touch {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-touch {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-touch {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-touch {\n    margin-left: 50%;\n  }\n  .column.is-7-touch {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-touch {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-touch {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-touch {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-touch {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-touch {\n    margin-left: 75%;\n  }\n  .column.is-10-touch {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-touch {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-touch {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-touch {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-touch {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-touch {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .column.is-narrow-desktop {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-desktop {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-desktop {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-desktop {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-desktop {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-desktop {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-desktop {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-desktop {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-desktop {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-desktop {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-desktop {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-desktop {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-desktop {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-desktop {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-desktop {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-desktop {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-desktop {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-desktop {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-desktop {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-desktop {\n    margin-left: 80%;\n  }\n  .column.is-0-desktop {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-desktop {\n    margin-left: 0%;\n  }\n  .column.is-1-desktop {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-desktop {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-desktop {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-desktop {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-desktop {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-desktop {\n    margin-left: 25%;\n  }\n  .column.is-4-desktop {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-desktop {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-desktop {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-desktop {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-desktop {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-desktop {\n    margin-left: 50%;\n  }\n  .column.is-7-desktop {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-desktop {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-desktop {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-desktop {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-desktop {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-desktop {\n    margin-left: 75%;\n  }\n  .column.is-10-desktop {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-desktop {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-desktop {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-desktop {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-desktop {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-desktop {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .column.is-narrow-widescreen {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-widescreen {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-widescreen {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-widescreen {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-widescreen {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-widescreen {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-widescreen {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-widescreen {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-widescreen {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-widescreen {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-widescreen {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-widescreen {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-widescreen {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-widescreen {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-widescreen {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-widescreen {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-widescreen {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-widescreen {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-widescreen {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-widescreen {\n    margin-left: 80%;\n  }\n  .column.is-0-widescreen {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-widescreen {\n    margin-left: 0%;\n  }\n  .column.is-1-widescreen {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-widescreen {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-widescreen {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-widescreen {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-widescreen {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-widescreen {\n    margin-left: 25%;\n  }\n  .column.is-4-widescreen {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-widescreen {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-widescreen {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-widescreen {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-widescreen {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-widescreen {\n    margin-left: 50%;\n  }\n  .column.is-7-widescreen {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-widescreen {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-widescreen {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-widescreen {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-widescreen {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-widescreen {\n    margin-left: 75%;\n  }\n  .column.is-10-widescreen {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-widescreen {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-widescreen {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-widescreen {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-widescreen {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-widescreen {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .column.is-narrow-fullhd {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-fullhd {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-fullhd {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-fullhd {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-fullhd {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-fullhd {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-fullhd {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-fullhd {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-fullhd {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-fullhd {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-fullhd {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-fullhd {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-fullhd {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-fullhd {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-fullhd {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-fullhd {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-fullhd {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-fullhd {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-fullhd {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-fullhd {\n    margin-left: 80%;\n  }\n  .column.is-0-fullhd {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-fullhd {\n    margin-left: 0%;\n  }\n  .column.is-1-fullhd {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-fullhd {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-fullhd {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-fullhd {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-fullhd {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-fullhd {\n    margin-left: 25%;\n  }\n  .column.is-4-fullhd {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-fullhd {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-fullhd {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-fullhd {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-fullhd {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-fullhd {\n    margin-left: 50%;\n  }\n  .column.is-7-fullhd {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-fullhd {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-fullhd {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-fullhd {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-fullhd {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-fullhd {\n    margin-left: 75%;\n  }\n  .column.is-10-fullhd {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-fullhd {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-fullhd {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-fullhd {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-fullhd {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-fullhd {\n    margin-left: 100%;\n  }\n}\n\n.columns {\n  margin-left: -0.75rem;\n  margin-right: -0.75rem;\n  margin-top: -0.75rem;\n}\n\n.columns:last-child {\n  margin-bottom: -0.75rem;\n}\n\n.columns:not(:last-child) {\n  margin-bottom: calc(1.5rem - 0.75rem);\n}\n\n.columns.is-centered {\n  justify-content: center;\n}\n\n.columns.is-gapless {\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 0;\n}\n\n.columns.is-gapless > .column {\n  margin: 0;\n  padding: 0 !important;\n}\n\n.columns.is-gapless:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.columns.is-gapless:last-child {\n  margin-bottom: 0;\n}\n\n.columns.is-mobile {\n  display: flex;\n}\n\n.columns.is-multiline {\n  flex-wrap: wrap;\n}\n\n.columns.is-vcentered {\n  align-items: center;\n}\n\n@media screen and (min-width: 769px), print {\n  .columns:not(.is-desktop) {\n    display: flex;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-desktop {\n    display: flex;\n  }\n}\n\n.columns.is-variable {\n  --columnGap: 0.75rem;\n  margin-left: calc(-1 * var(--columnGap));\n  margin-right: calc(-1 * var(--columnGap));\n}\n\n.columns.is-variable > .column {\n  padding-left: var(--columnGap);\n  padding-right: var(--columnGap);\n}\n\n.columns.is-variable.is-0 {\n  --columnGap: 0rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-0-mobile {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-0-tablet {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-0-tablet-only {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-0-touch {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-0-desktop {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-0-desktop-only {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-0-widescreen {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-0-widescreen-only {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-0-fullhd {\n    --columnGap: 0rem;\n  }\n}\n\n.columns.is-variable.is-1 {\n  --columnGap: 0.25rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-1-mobile {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-1-tablet {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-1-tablet-only {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-1-touch {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-1-desktop {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-1-desktop-only {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-1-widescreen {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-1-widescreen-only {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-1-fullhd {\n    --columnGap: 0.25rem;\n  }\n}\n\n.columns.is-variable.is-2 {\n  --columnGap: 0.5rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-2-mobile {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-2-tablet {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-2-tablet-only {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-2-touch {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-2-desktop {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-2-desktop-only {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-2-widescreen {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-2-widescreen-only {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-2-fullhd {\n    --columnGap: 0.5rem;\n  }\n}\n\n.columns.is-variable.is-3 {\n  --columnGap: 0.75rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-3-mobile {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-3-tablet {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-3-tablet-only {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-3-touch {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-3-desktop {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-3-desktop-only {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-3-widescreen {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-3-widescreen-only {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-3-fullhd {\n    --columnGap: 0.75rem;\n  }\n}\n\n.columns.is-variable.is-4 {\n  --columnGap: 1rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-4-mobile {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-4-tablet {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-4-tablet-only {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-4-touch {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-4-desktop {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-4-desktop-only {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-4-widescreen {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-4-widescreen-only {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-4-fullhd {\n    --columnGap: 1rem;\n  }\n}\n\n.columns.is-variable.is-5 {\n  --columnGap: 1.25rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-5-mobile {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-5-tablet {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-5-tablet-only {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-5-touch {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-5-desktop {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-5-desktop-only {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-5-widescreen {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-5-widescreen-only {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-5-fullhd {\n    --columnGap: 1.25rem;\n  }\n}\n\n.columns.is-variable.is-6 {\n  --columnGap: 1.5rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-6-mobile {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-6-tablet {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-6-tablet-only {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-6-touch {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-6-desktop {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-6-desktop-only {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-6-widescreen {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-6-widescreen-only {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-6-fullhd {\n    --columnGap: 1.5rem;\n  }\n}\n\n.columns.is-variable.is-7 {\n  --columnGap: 1.75rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-7-mobile {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-7-tablet {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-7-tablet-only {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-7-touch {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-7-desktop {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-7-desktop-only {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-7-widescreen {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-7-widescreen-only {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-7-fullhd {\n    --columnGap: 1.75rem;\n  }\n}\n\n.columns.is-variable.is-8 {\n  --columnGap: 2rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-8-mobile {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-8-tablet {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-8-tablet-only {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-8-touch {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-8-desktop {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-8-desktop-only {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-8-widescreen {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-8-widescreen-only {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-8-fullhd {\n    --columnGap: 2rem;\n  }\n}\n\n.tile {\n  align-items: stretch;\n  display: block;\n  flex-basis: 0;\n  flex-grow: 1;\n  flex-shrink: 1;\n  min-height: -webkit-min-content;\n  min-height: -moz-min-content;\n  min-height: min-content;\n}\n\n.tile.is-ancestor {\n  margin-left: -0.75rem;\n  margin-right: -0.75rem;\n  margin-top: -0.75rem;\n}\n\n.tile.is-ancestor:last-child {\n  margin-bottom: -0.75rem;\n}\n\n.tile.is-ancestor:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.tile.is-child {\n  margin: 0 !important;\n}\n\n.tile.is-parent {\n  padding: 0.75rem;\n}\n\n.tile.is-vertical {\n  flex-direction: column;\n}\n\n.tile.is-vertical > .tile.is-child:not(:last-child) {\n  margin-bottom: 1.5rem !important;\n}\n\n@media screen and (min-width: 769px), print {\n  .tile:not(.is-child) {\n    display: flex;\n  }\n  .tile.is-1 {\n    flex: none;\n    width: 8.33333%;\n  }\n  .tile.is-2 {\n    flex: none;\n    width: 16.66667%;\n  }\n  .tile.is-3 {\n    flex: none;\n    width: 25%;\n  }\n  .tile.is-4 {\n    flex: none;\n    width: 33.33333%;\n  }\n  .tile.is-5 {\n    flex: none;\n    width: 41.66667%;\n  }\n  .tile.is-6 {\n    flex: none;\n    width: 50%;\n  }\n  .tile.is-7 {\n    flex: none;\n    width: 58.33333%;\n  }\n  .tile.is-8 {\n    flex: none;\n    width: 66.66667%;\n  }\n  .tile.is-9 {\n    flex: none;\n    width: 75%;\n  }\n  .tile.is-10 {\n    flex: none;\n    width: 83.33333%;\n  }\n  .tile.is-11 {\n    flex: none;\n    width: 91.66667%;\n  }\n  .tile.is-12 {\n    flex: none;\n    width: 100%;\n  }\n}\n\n/* Bulma Helpers */\n.has-text-white {\n  color: white !important;\n}\n\na.has-text-white:hover, a.has-text-white:focus {\n  color: #e6e6e6 !important;\n}\n\n.has-background-white {\n  background-color: white !important;\n}\n\n.has-text-black {\n  color: #0a0a0a !important;\n}\n\na.has-text-black:hover, a.has-text-black:focus {\n  color: black !important;\n}\n\n.has-background-black {\n  background-color: #0a0a0a !important;\n}\n\n.has-text-light {\n  color: whitesmoke !important;\n}\n\na.has-text-light:hover, a.has-text-light:focus {\n  color: #dbdbdb !important;\n}\n\n.has-background-light {\n  background-color: whitesmoke !important;\n}\n\n.has-text-dark {\n  color: #363636 !important;\n}\n\na.has-text-dark:hover, a.has-text-dark:focus {\n  color: #1c1c1c !important;\n}\n\n.has-background-dark {\n  background-color: #363636 !important;\n}\n\n.has-text-primary {\n  color: #00d1b2 !important;\n}\n\na.has-text-primary:hover, a.has-text-primary:focus {\n  color: #009e86 !important;\n}\n\n.has-background-primary {\n  background-color: #00d1b2 !important;\n}\n\n.has-text-primary-light {\n  color: #ebfffc !important;\n}\n\na.has-text-primary-light:hover, a.has-text-primary-light:focus {\n  color: #b8fff4 !important;\n}\n\n.has-background-primary-light {\n  background-color: #ebfffc !important;\n}\n\n.has-text-primary-dark {\n  color: #00947e !important;\n}\n\na.has-text-primary-dark:hover, a.has-text-primary-dark:focus {\n  color: #00c7a9 !important;\n}\n\n.has-background-primary-dark {\n  background-color: #00947e !important;\n}\n\n.has-text-link {\n  color: #485fc7 !important;\n}\n\na.has-text-link:hover, a.has-text-link:focus {\n  color: #3449a8 !important;\n}\n\n.has-background-link {\n  background-color: #485fc7 !important;\n}\n\n.has-text-link-light {\n  color: #eff1fa !important;\n}\n\na.has-text-link-light:hover, a.has-text-link-light:focus {\n  color: #c8cfee !important;\n}\n\n.has-background-link-light {\n  background-color: #eff1fa !important;\n}\n\n.has-text-link-dark {\n  color: #3850b7 !important;\n}\n\na.has-text-link-dark:hover, a.has-text-link-dark:focus {\n  color: #576dcb !important;\n}\n\n.has-background-link-dark {\n  background-color: #3850b7 !important;\n}\n\n.has-text-info {\n  color: #3e8ed0 !important;\n}\n\na.has-text-info:hover, a.has-text-info:focus {\n  color: #2b74b1 !important;\n}\n\n.has-background-info {\n  background-color: #3e8ed0 !important;\n}\n\n.has-text-info-light {\n  color: #eff5fb !important;\n}\n\na.has-text-info-light:hover, a.has-text-info-light:focus {\n  color: #c6ddf1 !important;\n}\n\n.has-background-info-light {\n  background-color: #eff5fb !important;\n}\n\n.has-text-info-dark {\n  color: #296fa8 !important;\n}\n\na.has-text-info-dark:hover, a.has-text-info-dark:focus {\n  color: #368ace !important;\n}\n\n.has-background-info-dark {\n  background-color: #296fa8 !important;\n}\n\n.has-text-success {\n  color: #48c78e !important;\n}\n\na.has-text-success:hover, a.has-text-success:focus {\n  color: #34a873 !important;\n}\n\n.has-background-success {\n  background-color: #48c78e !important;\n}\n\n.has-text-success-light {\n  color: #effaf5 !important;\n}\n\na.has-text-success-light:hover, a.has-text-success-light:focus {\n  color: #c8eedd !important;\n}\n\n.has-background-success-light {\n  background-color: #effaf5 !important;\n}\n\n.has-text-success-dark {\n  color: #257953 !important;\n}\n\na.has-text-success-dark:hover, a.has-text-success-dark:focus {\n  color: #31a06e !important;\n}\n\n.has-background-success-dark {\n  background-color: #257953 !important;\n}\n\n.has-text-warning {\n  color: #ffe08a !important;\n}\n\na.has-text-warning:hover, a.has-text-warning:focus {\n  color: #ffd257 !important;\n}\n\n.has-background-warning {\n  background-color: #ffe08a !important;\n}\n\n.has-text-warning-light {\n  color: #fffaeb !important;\n}\n\na.has-text-warning-light:hover, a.has-text-warning-light:focus {\n  color: #ffecb8 !important;\n}\n\n.has-background-warning-light {\n  background-color: #fffaeb !important;\n}\n\n.has-text-warning-dark {\n  color: #946c00 !important;\n}\n\na.has-text-warning-dark:hover, a.has-text-warning-dark:focus {\n  color: #c79200 !important;\n}\n\n.has-background-warning-dark {\n  background-color: #946c00 !important;\n}\n\n.has-text-danger {\n  color: #f14668 !important;\n}\n\na.has-text-danger:hover, a.has-text-danger:focus {\n  color: #ee1742 !important;\n}\n\n.has-background-danger {\n  background-color: #f14668 !important;\n}\n\n.has-text-danger-light {\n  color: #feecf0 !important;\n}\n\na.has-text-danger-light:hover, a.has-text-danger-light:focus {\n  color: #fabdc9 !important;\n}\n\n.has-background-danger-light {\n  background-color: #feecf0 !important;\n}\n\n.has-text-danger-dark {\n  color: #cc0f35 !important;\n}\n\na.has-text-danger-dark:hover, a.has-text-danger-dark:focus {\n  color: #ee2049 !important;\n}\n\n.has-background-danger-dark {\n  background-color: #cc0f35 !important;\n}\n\n.has-text-black-bis {\n  color: #121212 !important;\n}\n\n.has-background-black-bis {\n  background-color: #121212 !important;\n}\n\n.has-text-black-ter {\n  color: #242424 !important;\n}\n\n.has-background-black-ter {\n  background-color: #242424 !important;\n}\n\n.has-text-grey-darker {\n  color: #363636 !important;\n}\n\n.has-background-grey-darker {\n  background-color: #363636 !important;\n}\n\n.has-text-grey-dark {\n  color: #4a4a4a !important;\n}\n\n.has-background-grey-dark {\n  background-color: #4a4a4a !important;\n}\n\n.has-text-grey {\n  color: #7a7a7a !important;\n}\n\n.has-background-grey {\n  background-color: #7a7a7a !important;\n}\n\n.has-text-grey-light {\n  color: #b5b5b5 !important;\n}\n\n.has-background-grey-light {\n  background-color: #b5b5b5 !important;\n}\n\n.has-text-grey-lighter {\n  color: #dbdbdb !important;\n}\n\n.has-background-grey-lighter {\n  background-color: #dbdbdb !important;\n}\n\n.has-text-white-ter {\n  color: whitesmoke !important;\n}\n\n.has-background-white-ter {\n  background-color: whitesmoke !important;\n}\n\n.has-text-white-bis {\n  color: #fafafa !important;\n}\n\n.has-background-white-bis {\n  background-color: #fafafa !important;\n}\n\n.is-flex-direction-row {\n  flex-direction: row !important;\n}\n\n.is-flex-direction-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.is-flex-direction-column {\n  flex-direction: column !important;\n}\n\n.is-flex-direction-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.is-flex-wrap-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.is-flex-wrap-wrap {\n  flex-wrap: wrap !important;\n}\n\n.is-flex-wrap-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.is-justify-content-flex-start {\n  justify-content: flex-start !important;\n}\n\n.is-justify-content-flex-end {\n  justify-content: flex-end !important;\n}\n\n.is-justify-content-center {\n  justify-content: center !important;\n}\n\n.is-justify-content-space-between {\n  justify-content: space-between !important;\n}\n\n.is-justify-content-space-around {\n  justify-content: space-around !important;\n}\n\n.is-justify-content-space-evenly {\n  justify-content: space-evenly !important;\n}\n\n.is-justify-content-start {\n  justify-content: start !important;\n}\n\n.is-justify-content-end {\n  justify-content: end !important;\n}\n\n.is-justify-content-left {\n  justify-content: left !important;\n}\n\n.is-justify-content-right {\n  justify-content: right !important;\n}\n\n.is-align-content-flex-start {\n  align-content: flex-start !important;\n}\n\n.is-align-content-flex-end {\n  align-content: flex-end !important;\n}\n\n.is-align-content-center {\n  align-content: center !important;\n}\n\n.is-align-content-space-between {\n  align-content: space-between !important;\n}\n\n.is-align-content-space-around {\n  align-content: space-around !important;\n}\n\n.is-align-content-space-evenly {\n  align-content: space-evenly !important;\n}\n\n.is-align-content-stretch {\n  align-content: stretch !important;\n}\n\n.is-align-content-start {\n  align-content: start !important;\n}\n\n.is-align-content-end {\n  align-content: end !important;\n}\n\n.is-align-content-baseline {\n  align-content: baseline !important;\n}\n\n.is-align-items-stretch {\n  align-items: stretch !important;\n}\n\n.is-align-items-flex-start {\n  align-items: flex-start !important;\n}\n\n.is-align-items-flex-end {\n  align-items: flex-end !important;\n}\n\n.is-align-items-center {\n  align-items: center !important;\n}\n\n.is-align-items-baseline {\n  align-items: baseline !important;\n}\n\n.is-align-items-start {\n  align-items: start !important;\n}\n\n.is-align-items-end {\n  align-items: end !important;\n}\n\n.is-align-items-self-start {\n  align-items: self-start !important;\n}\n\n.is-align-items-self-end {\n  align-items: self-end !important;\n}\n\n.is-align-self-auto {\n  align-self: auto !important;\n}\n\n.is-align-self-flex-start {\n  align-self: flex-start !important;\n}\n\n.is-align-self-flex-end {\n  align-self: flex-end !important;\n}\n\n.is-align-self-center {\n  align-self: center !important;\n}\n\n.is-align-self-baseline {\n  align-self: baseline !important;\n}\n\n.is-align-self-stretch {\n  align-self: stretch !important;\n}\n\n.is-flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.is-flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.is-flex-grow-2 {\n  flex-grow: 2 !important;\n}\n\n.is-flex-grow-3 {\n  flex-grow: 3 !important;\n}\n\n.is-flex-grow-4 {\n  flex-grow: 4 !important;\n}\n\n.is-flex-grow-5 {\n  flex-grow: 5 !important;\n}\n\n.is-flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.is-flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.is-flex-shrink-2 {\n  flex-shrink: 2 !important;\n}\n\n.is-flex-shrink-3 {\n  flex-shrink: 3 !important;\n}\n\n.is-flex-shrink-4 {\n  flex-shrink: 4 !important;\n}\n\n.is-flex-shrink-5 {\n  flex-shrink: 5 !important;\n}\n\n.is-clearfix::after {\n  clear: both;\n  content: \" \";\n  display: table;\n}\n\n.is-pulled-left {\n  float: left !important;\n}\n\n.is-pulled-right {\n  float: right !important;\n}\n\n.is-radiusless {\n  border-radius: 0 !important;\n}\n\n.is-shadowless {\n  box-shadow: none !important;\n}\n\n.is-clickable {\n  cursor: pointer !important;\n  pointer-events: all !important;\n}\n\n.is-clipped {\n  overflow: hidden !important;\n}\n\n.is-relative {\n  position: relative !important;\n}\n\n.is-marginless {\n  margin: 0 !important;\n}\n\n.is-paddingless {\n  padding: 0 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mr-0 {\n  margin-right: 0 !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.ml-0 {\n  margin-left: 0 !important;\n}\n\n.mx-0 {\n  margin-left: 0 !important;\n  margin-right: 0 !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mr-1 {\n  margin-right: 0.25rem !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.ml-1 {\n  margin-left: 0.25rem !important;\n}\n\n.mx-1 {\n  margin-left: 0.25rem !important;\n  margin-right: 0.25rem !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mr-2 {\n  margin-right: 0.5rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.ml-2 {\n  margin-left: 0.5rem !important;\n}\n\n.mx-2 {\n  margin-left: 0.5rem !important;\n  margin-right: 0.5rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 0.75rem !important;\n}\n\n.mt-3 {\n  margin-top: 0.75rem !important;\n}\n\n.mr-3 {\n  margin-right: 0.75rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 0.75rem !important;\n}\n\n.ml-3 {\n  margin-left: 0.75rem !important;\n}\n\n.mx-3 {\n  margin-left: 0.75rem !important;\n  margin-right: 0.75rem !important;\n}\n\n.my-3 {\n  margin-top: 0.75rem !important;\n  margin-bottom: 0.75rem !important;\n}\n\n.m-4 {\n  margin: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1rem !important;\n}\n\n.mr-4 {\n  margin-right: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1rem !important;\n}\n\n.ml-4 {\n  margin-left: 1rem !important;\n}\n\n.mx-4 {\n  margin-left: 1rem !important;\n  margin-right: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.m-5 {\n  margin: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 1.5rem !important;\n}\n\n.mr-5 {\n  margin-right: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 1.5rem !important;\n}\n\n.ml-5 {\n  margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-left: 1.5rem !important;\n  margin-right: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.m-6 {\n  margin: 3rem !important;\n}\n\n.mt-6 {\n  margin-top: 3rem !important;\n}\n\n.mr-6 {\n  margin-right: 3rem !important;\n}\n\n.mb-6 {\n  margin-bottom: 3rem !important;\n}\n\n.ml-6 {\n  margin-left: 3rem !important;\n}\n\n.mx-6 {\n  margin-left: 3rem !important;\n  margin-right: 3rem !important;\n}\n\n.my-6 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.mr-auto {\n  margin-right: auto !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ml-auto {\n  margin-left: auto !important;\n}\n\n.mx-auto {\n  margin-left: auto !important;\n  margin-right: auto !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pr-0 {\n  padding-right: 0 !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pl-0 {\n  padding-left: 0 !important;\n}\n\n.px-0 {\n  padding-left: 0 !important;\n  padding-right: 0 !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pr-1 {\n  padding-right: 0.25rem !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pl-1 {\n  padding-left: 0.25rem !important;\n}\n\n.px-1 {\n  padding-left: 0.25rem !important;\n  padding-right: 0.25rem !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pr-2 {\n  padding-right: 0.5rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pl-2 {\n  padding-left: 0.5rem !important;\n}\n\n.px-2 {\n  padding-left: 0.5rem !important;\n  padding-right: 0.5rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 0.75rem !important;\n}\n\n.pt-3 {\n  padding-top: 0.75rem !important;\n}\n\n.pr-3 {\n  padding-right: 0.75rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 0.75rem !important;\n}\n\n.pl-3 {\n  padding-left: 0.75rem !important;\n}\n\n.px-3 {\n  padding-left: 0.75rem !important;\n  padding-right: 0.75rem !important;\n}\n\n.py-3 {\n  padding-top: 0.75rem !important;\n  padding-bottom: 0.75rem !important;\n}\n\n.p-4 {\n  padding: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1rem !important;\n}\n\n.pr-4 {\n  padding-right: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1rem !important;\n}\n\n.pl-4 {\n  padding-left: 1rem !important;\n}\n\n.px-4 {\n  padding-left: 1rem !important;\n  padding-right: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.p-5 {\n  padding: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 1.5rem !important;\n}\n\n.pr-5 {\n  padding-right: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pl-5 {\n  padding-left: 1.5rem !important;\n}\n\n.px-5 {\n  padding-left: 1.5rem !important;\n  padding-right: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.p-6 {\n  padding: 3rem !important;\n}\n\n.pt-6 {\n  padding-top: 3rem !important;\n}\n\n.pr-6 {\n  padding-right: 3rem !important;\n}\n\n.pb-6 {\n  padding-bottom: 3rem !important;\n}\n\n.pl-6 {\n  padding-left: 3rem !important;\n}\n\n.px-6 {\n  padding-left: 3rem !important;\n  padding-right: 3rem !important;\n}\n\n.py-6 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.p-auto {\n  padding: auto !important;\n}\n\n.pt-auto {\n  padding-top: auto !important;\n}\n\n.pr-auto {\n  padding-right: auto !important;\n}\n\n.pb-auto {\n  padding-bottom: auto !important;\n}\n\n.pl-auto {\n  padding-left: auto !important;\n}\n\n.px-auto {\n  padding-left: auto !important;\n  padding-right: auto !important;\n}\n\n.py-auto {\n  padding-top: auto !important;\n  padding-bottom: auto !important;\n}\n\n.is-size-1 {\n  font-size: 3rem !important;\n}\n\n.is-size-2 {\n  font-size: 2.5rem !important;\n}\n\n.is-size-3 {\n  font-size: 2rem !important;\n}\n\n.is-size-4 {\n  font-size: 1.5rem !important;\n}\n\n.is-size-5 {\n  font-size: 1.25rem !important;\n}\n\n.is-size-6 {\n  font-size: 1rem !important;\n}\n\n.is-size-7 {\n  font-size: 0.75rem !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-size-1-mobile {\n    font-size: 3rem !important;\n  }\n  .is-size-2-mobile {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-mobile {\n    font-size: 2rem !important;\n  }\n  .is-size-4-mobile {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-mobile {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-mobile {\n    font-size: 1rem !important;\n  }\n  .is-size-7-mobile {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-size-1-tablet {\n    font-size: 3rem !important;\n  }\n  .is-size-2-tablet {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-tablet {\n    font-size: 2rem !important;\n  }\n  .is-size-4-tablet {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-tablet {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-tablet {\n    font-size: 1rem !important;\n  }\n  .is-size-7-tablet {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-size-1-touch {\n    font-size: 3rem !important;\n  }\n  .is-size-2-touch {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-touch {\n    font-size: 2rem !important;\n  }\n  .is-size-4-touch {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-touch {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-touch {\n    font-size: 1rem !important;\n  }\n  .is-size-7-touch {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-size-1-desktop {\n    font-size: 3rem !important;\n  }\n  .is-size-2-desktop {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-desktop {\n    font-size: 2rem !important;\n  }\n  .is-size-4-desktop {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-desktop {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-desktop {\n    font-size: 1rem !important;\n  }\n  .is-size-7-desktop {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-size-1-widescreen {\n    font-size: 3rem !important;\n  }\n  .is-size-2-widescreen {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-widescreen {\n    font-size: 2rem !important;\n  }\n  .is-size-4-widescreen {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-widescreen {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-widescreen {\n    font-size: 1rem !important;\n  }\n  .is-size-7-widescreen {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-size-1-fullhd {\n    font-size: 3rem !important;\n  }\n  .is-size-2-fullhd {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-fullhd {\n    font-size: 2rem !important;\n  }\n  .is-size-4-fullhd {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-fullhd {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-fullhd {\n    font-size: 1rem !important;\n  }\n  .is-size-7-fullhd {\n    font-size: 0.75rem !important;\n  }\n}\n\n.has-text-centered {\n  text-align: center !important;\n}\n\n.has-text-justified {\n  text-align: justify !important;\n}\n\n.has-text-left {\n  text-align: left !important;\n}\n\n.has-text-right {\n  text-align: right !important;\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-centered-mobile {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-centered-tablet {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-centered-tablet-only {\n    text-align: center !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-centered-touch {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-centered-desktop {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-centered-desktop-only {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-centered-widescreen {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-centered-widescreen-only {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-centered-fullhd {\n    text-align: center !important;\n  }\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-justified-mobile {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-justified-tablet {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-justified-tablet-only {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-justified-touch {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-justified-desktop {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-justified-desktop-only {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-justified-widescreen {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-justified-widescreen-only {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-justified-fullhd {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-left-mobile {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-left-tablet {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-left-tablet-only {\n    text-align: left !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-left-touch {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-left-desktop {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-left-desktop-only {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-left-widescreen {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-left-widescreen-only {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-left-fullhd {\n    text-align: left !important;\n  }\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-right-mobile {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-right-tablet {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-right-tablet-only {\n    text-align: right !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-right-touch {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-right-desktop {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-right-desktop-only {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-right-widescreen {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-right-widescreen-only {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-right-fullhd {\n    text-align: right !important;\n  }\n}\n\n.is-capitalized {\n  text-transform: capitalize !important;\n}\n\n.is-lowercase {\n  text-transform: lowercase !important;\n}\n\n.is-uppercase {\n  text-transform: uppercase !important;\n}\n\n.is-italic {\n  font-style: italic !important;\n}\n\n.is-underlined {\n  text-decoration: underline !important;\n}\n\n.has-text-weight-light {\n  font-weight: 300 !important;\n}\n\n.has-text-weight-normal {\n  font-weight: 400 !important;\n}\n\n.has-text-weight-medium {\n  font-weight: 500 !important;\n}\n\n.has-text-weight-semibold {\n  font-weight: 600 !important;\n}\n\n.has-text-weight-bold {\n  font-weight: 700 !important;\n}\n\n.is-family-primary {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif !important;\n}\n\n.is-family-secondary {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif !important;\n}\n\n.is-family-sans-serif {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif !important;\n}\n\n.is-family-monospace {\n  font-family: monospace !important;\n}\n\n.is-family-code {\n  font-family: monospace !important;\n}\n\n.is-block {\n  display: block !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-block-mobile {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-block-tablet {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-block-tablet-only {\n    display: block !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-block-touch {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-block-desktop {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-block-desktop-only {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-block-widescreen {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-block-widescreen-only {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-block-fullhd {\n    display: block !important;\n  }\n}\n\n.is-flex {\n  display: flex !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-flex-mobile {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-flex-tablet {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-flex-tablet-only {\n    display: flex !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-flex-touch {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-flex-desktop {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-flex-desktop-only {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-flex-widescreen {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-flex-widescreen-only {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-flex-fullhd {\n    display: flex !important;\n  }\n}\n\n.is-inline {\n  display: inline !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-inline-mobile {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-inline-tablet {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-inline-tablet-only {\n    display: inline !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-inline-touch {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-inline-desktop {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-inline-desktop-only {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-inline-widescreen {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-inline-widescreen-only {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-inline-fullhd {\n    display: inline !important;\n  }\n}\n\n.is-inline-block {\n  display: inline-block !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-inline-block-mobile {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-inline-block-tablet {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-inline-block-tablet-only {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-inline-block-touch {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-inline-block-desktop {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-inline-block-desktop-only {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-inline-block-widescreen {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-inline-block-widescreen-only {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-inline-block-fullhd {\n    display: inline-block !important;\n  }\n}\n\n.is-inline-flex {\n  display: inline-flex !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-inline-flex-mobile {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-inline-flex-tablet {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-inline-flex-tablet-only {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-inline-flex-touch {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-inline-flex-desktop {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-inline-flex-desktop-only {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-inline-flex-widescreen {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-inline-flex-widescreen-only {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-inline-flex-fullhd {\n    display: inline-flex !important;\n  }\n}\n\n.is-hidden {\n  display: none !important;\n}\n\n.is-sr-only {\n  border: none !important;\n  clip: rect(0, 0, 0, 0) !important;\n  height: 0.01em !important;\n  overflow: hidden !important;\n  padding: 0 !important;\n  position: absolute !important;\n  white-space: nowrap !important;\n  width: 0.01em !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-hidden-mobile {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-hidden-tablet {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-hidden-tablet-only {\n    display: none !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-hidden-touch {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-hidden-desktop {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-hidden-desktop-only {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-hidden-widescreen {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-hidden-widescreen-only {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-hidden-fullhd {\n    display: none !important;\n  }\n}\n\n.is-invisible {\n  visibility: hidden !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-invisible-mobile {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-invisible-tablet {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-invisible-tablet-only {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-invisible-touch {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-invisible-desktop {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-invisible-desktop-only {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-invisible-widescreen {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-invisible-widescreen-only {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-invisible-fullhd {\n    visibility: hidden !important;\n  }\n}\n\n/* Bulma Layout */\n.hero {\n  align-items: stretch;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n}\n\n.hero .navbar {\n  background: none;\n}\n\n.hero .tabs ul {\n  border-bottom: none;\n}\n\n.hero.is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-white strong {\n  color: inherit;\n}\n\n.hero.is-white .title {\n  color: #0a0a0a;\n}\n\n.hero.is-white .subtitle {\n  color: rgba(10, 10, 10, 0.9);\n}\n\n.hero.is-white .subtitle a:not(.button),\n.hero.is-white .subtitle strong {\n  color: #0a0a0a;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-white .navbar-menu {\n    background-color: white;\n  }\n}\n\n.hero.is-white .navbar-item,\n.hero.is-white .navbar-link {\n  color: rgba(10, 10, 10, 0.7);\n}\n\n.hero.is-white a.navbar-item:hover, .hero.is-white a.navbar-item.is-active,\n.hero.is-white .navbar-link:hover,\n.hero.is-white .navbar-link.is-active {\n  background-color: #f2f2f2;\n  color: #0a0a0a;\n}\n\n.hero.is-white .tabs a {\n  color: #0a0a0a;\n  opacity: 0.9;\n}\n\n.hero.is-white .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-white .tabs li.is-active a {\n  color: white !important;\n  opacity: 1;\n}\n\n.hero.is-white .tabs.is-boxed a, .hero.is-white .tabs.is-toggle a {\n  color: #0a0a0a;\n}\n\n.hero.is-white .tabs.is-boxed a:hover, .hero.is-white .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-white .tabs.is-boxed li.is-active a, .hero.is-white .tabs.is-boxed li.is-active a:hover, .hero.is-white .tabs.is-toggle li.is-active a, .hero.is-white .tabs.is-toggle li.is-active a:hover {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  color: white;\n}\n\n.hero.is-white.is-bold {\n  background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-white.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%);\n  }\n}\n\n.hero.is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-black strong {\n  color: inherit;\n}\n\n.hero.is-black .title {\n  color: white;\n}\n\n.hero.is-black .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-black .subtitle a:not(.button),\n.hero.is-black .subtitle strong {\n  color: white;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-black .navbar-menu {\n    background-color: #0a0a0a;\n  }\n}\n\n.hero.is-black .navbar-item,\n.hero.is-black .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-black a.navbar-item:hover, .hero.is-black a.navbar-item.is-active,\n.hero.is-black .navbar-link:hover,\n.hero.is-black .navbar-link.is-active {\n  background-color: black;\n  color: white;\n}\n\n.hero.is-black .tabs a {\n  color: white;\n  opacity: 0.9;\n}\n\n.hero.is-black .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-black .tabs li.is-active a {\n  color: #0a0a0a !important;\n  opacity: 1;\n}\n\n.hero.is-black .tabs.is-boxed a, .hero.is-black .tabs.is-toggle a {\n  color: white;\n}\n\n.hero.is-black .tabs.is-boxed a:hover, .hero.is-black .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-black .tabs.is-boxed li.is-active a, .hero.is-black .tabs.is-boxed li.is-active a:hover, .hero.is-black .tabs.is-toggle li.is-active a, .hero.is-black .tabs.is-toggle li.is-active a:hover {\n  background-color: white;\n  border-color: white;\n  color: #0a0a0a;\n}\n\n.hero.is-black.is-bold {\n  background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-black.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%);\n  }\n}\n\n.hero.is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-light strong {\n  color: inherit;\n}\n\n.hero.is-light .title {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light .subtitle {\n  color: rgba(0, 0, 0, 0.9);\n}\n\n.hero.is-light .subtitle a:not(.button),\n.hero.is-light .subtitle strong {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-light .navbar-menu {\n    background-color: whitesmoke;\n  }\n}\n\n.hero.is-light .navbar-item,\n.hero.is-light .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light a.navbar-item:hover, .hero.is-light a.navbar-item.is-active,\n.hero.is-light .navbar-link:hover,\n.hero.is-light .navbar-link.is-active {\n  background-color: #e8e8e8;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light .tabs a {\n  color: rgba(0, 0, 0, 0.7);\n  opacity: 0.9;\n}\n\n.hero.is-light .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-light .tabs li.is-active a {\n  color: whitesmoke !important;\n  opacity: 1;\n}\n\n.hero.is-light .tabs.is-boxed a, .hero.is-light .tabs.is-toggle a {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light .tabs.is-boxed a:hover, .hero.is-light .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-light .tabs.is-boxed li.is-active a, .hero.is-light .tabs.is-boxed li.is-active a:hover, .hero.is-light .tabs.is-toggle li.is-active a, .hero.is-light .tabs.is-toggle li.is-active a:hover {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: rgba(0, 0, 0, 0.7);\n  color: whitesmoke;\n}\n\n.hero.is-light.is-bold {\n  background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-light.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%);\n  }\n}\n\n.hero.is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-dark strong {\n  color: inherit;\n}\n\n.hero.is-dark .title {\n  color: #fff;\n}\n\n.hero.is-dark .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-dark .subtitle a:not(.button),\n.hero.is-dark .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-dark .navbar-menu {\n    background-color: #363636;\n  }\n}\n\n.hero.is-dark .navbar-item,\n.hero.is-dark .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-dark a.navbar-item:hover, .hero.is-dark a.navbar-item.is-active,\n.hero.is-dark .navbar-link:hover,\n.hero.is-dark .navbar-link.is-active {\n  background-color: #292929;\n  color: #fff;\n}\n\n.hero.is-dark .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-dark .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-dark .tabs li.is-active a {\n  color: #363636 !important;\n  opacity: 1;\n}\n\n.hero.is-dark .tabs.is-boxed a, .hero.is-dark .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-dark .tabs.is-boxed a:hover, .hero.is-dark .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-dark .tabs.is-boxed li.is-active a, .hero.is-dark .tabs.is-boxed li.is-active a:hover, .hero.is-dark .tabs.is-toggle li.is-active a, .hero.is-dark .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #363636;\n}\n\n.hero.is-dark.is-bold {\n  background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-dark.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%);\n  }\n}\n\n.hero.is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-primary strong {\n  color: inherit;\n}\n\n.hero.is-primary .title {\n  color: #fff;\n}\n\n.hero.is-primary .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-primary .subtitle a:not(.button),\n.hero.is-primary .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-primary .navbar-menu {\n    background-color: #00d1b2;\n  }\n}\n\n.hero.is-primary .navbar-item,\n.hero.is-primary .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-primary a.navbar-item:hover, .hero.is-primary a.navbar-item.is-active,\n.hero.is-primary .navbar-link:hover,\n.hero.is-primary .navbar-link.is-active {\n  background-color: #00b89c;\n  color: #fff;\n}\n\n.hero.is-primary .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-primary .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-primary .tabs li.is-active a {\n  color: #00d1b2 !important;\n  opacity: 1;\n}\n\n.hero.is-primary .tabs.is-boxed a, .hero.is-primary .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-primary .tabs.is-boxed a:hover, .hero.is-primary .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-primary .tabs.is-boxed li.is-active a, .hero.is-primary .tabs.is-boxed li.is-active a:hover, .hero.is-primary .tabs.is-toggle li.is-active a, .hero.is-primary .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #00d1b2;\n}\n\n.hero.is-primary.is-bold {\n  background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-primary.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%);\n  }\n}\n\n.hero.is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-link strong {\n  color: inherit;\n}\n\n.hero.is-link .title {\n  color: #fff;\n}\n\n.hero.is-link .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-link .subtitle a:not(.button),\n.hero.is-link .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-link .navbar-menu {\n    background-color: #485fc7;\n  }\n}\n\n.hero.is-link .navbar-item,\n.hero.is-link .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-link a.navbar-item:hover, .hero.is-link a.navbar-item.is-active,\n.hero.is-link .navbar-link:hover,\n.hero.is-link .navbar-link.is-active {\n  background-color: #3a51bb;\n  color: #fff;\n}\n\n.hero.is-link .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-link .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-link .tabs li.is-active a {\n  color: #485fc7 !important;\n  opacity: 1;\n}\n\n.hero.is-link .tabs.is-boxed a, .hero.is-link .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-link .tabs.is-boxed a:hover, .hero.is-link .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-link .tabs.is-boxed li.is-active a, .hero.is-link .tabs.is-boxed li.is-active a:hover, .hero.is-link .tabs.is-toggle li.is-active a, .hero.is-link .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #485fc7;\n}\n\n.hero.is-link.is-bold {\n  background-image: linear-gradient(141deg, #2959b3 0%, #485fc7 71%, #5658d2 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-link.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #2959b3 0%, #485fc7 71%, #5658d2 100%);\n  }\n}\n\n.hero.is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-info strong {\n  color: inherit;\n}\n\n.hero.is-info .title {\n  color: #fff;\n}\n\n.hero.is-info .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-info .subtitle a:not(.button),\n.hero.is-info .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-info .navbar-menu {\n    background-color: #3e8ed0;\n  }\n}\n\n.hero.is-info .navbar-item,\n.hero.is-info .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-info a.navbar-item:hover, .hero.is-info a.navbar-item.is-active,\n.hero.is-info .navbar-link:hover,\n.hero.is-info .navbar-link.is-active {\n  background-color: #3082c5;\n  color: #fff;\n}\n\n.hero.is-info .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-info .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-info .tabs li.is-active a {\n  color: #3e8ed0 !important;\n  opacity: 1;\n}\n\n.hero.is-info .tabs.is-boxed a, .hero.is-info .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-info .tabs.is-boxed a:hover, .hero.is-info .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-info .tabs.is-boxed li.is-active a, .hero.is-info .tabs.is-boxed li.is-active a:hover, .hero.is-info .tabs.is-toggle li.is-active a, .hero.is-info .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #3e8ed0;\n}\n\n.hero.is-info.is-bold {\n  background-image: linear-gradient(141deg, #208fbc 0%, #3e8ed0 71%, #4d83db 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-info.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #208fbc 0%, #3e8ed0 71%, #4d83db 100%);\n  }\n}\n\n.hero.is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-success strong {\n  color: inherit;\n}\n\n.hero.is-success .title {\n  color: #fff;\n}\n\n.hero.is-success .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-success .subtitle a:not(.button),\n.hero.is-success .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-success .navbar-menu {\n    background-color: #48c78e;\n  }\n}\n\n.hero.is-success .navbar-item,\n.hero.is-success .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-success a.navbar-item:hover, .hero.is-success a.navbar-item.is-active,\n.hero.is-success .navbar-link:hover,\n.hero.is-success .navbar-link.is-active {\n  background-color: #3abb81;\n  color: #fff;\n}\n\n.hero.is-success .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-success .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-success .tabs li.is-active a {\n  color: #48c78e !important;\n  opacity: 1;\n}\n\n.hero.is-success .tabs.is-boxed a, .hero.is-success .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-success .tabs.is-boxed a:hover, .hero.is-success .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-success .tabs.is-boxed li.is-active a, .hero.is-success .tabs.is-boxed li.is-active a:hover, .hero.is-success .tabs.is-toggle li.is-active a, .hero.is-success .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #48c78e;\n}\n\n.hero.is-success.is-bold {\n  background-image: linear-gradient(141deg, #29b35e 0%, #48c78e 71%, #56d2af 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-success.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #29b35e 0%, #48c78e 71%, #56d2af 100%);\n  }\n}\n\n.hero.is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-warning strong {\n  color: inherit;\n}\n\n.hero.is-warning .title {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning .subtitle {\n  color: rgba(0, 0, 0, 0.9);\n}\n\n.hero.is-warning .subtitle a:not(.button),\n.hero.is-warning .subtitle strong {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-warning .navbar-menu {\n    background-color: #ffe08a;\n  }\n}\n\n.hero.is-warning .navbar-item,\n.hero.is-warning .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning a.navbar-item:hover, .hero.is-warning a.navbar-item.is-active,\n.hero.is-warning .navbar-link:hover,\n.hero.is-warning .navbar-link.is-active {\n  background-color: #ffd970;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning .tabs a {\n  color: rgba(0, 0, 0, 0.7);\n  opacity: 0.9;\n}\n\n.hero.is-warning .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-warning .tabs li.is-active a {\n  color: #ffe08a !important;\n  opacity: 1;\n}\n\n.hero.is-warning .tabs.is-boxed a, .hero.is-warning .tabs.is-toggle a {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning .tabs.is-boxed a:hover, .hero.is-warning .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-warning .tabs.is-boxed li.is-active a, .hero.is-warning .tabs.is-boxed li.is-active a:hover, .hero.is-warning .tabs.is-toggle li.is-active a, .hero.is-warning .tabs.is-toggle li.is-active a:hover {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: rgba(0, 0, 0, 0.7);\n  color: #ffe08a;\n}\n\n.hero.is-warning.is-bold {\n  background-image: linear-gradient(141deg, #ffb657 0%, #ffe08a 71%, #fff6a3 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-warning.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #ffb657 0%, #ffe08a 71%, #fff6a3 100%);\n  }\n}\n\n.hero.is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-danger strong {\n  color: inherit;\n}\n\n.hero.is-danger .title {\n  color: #fff;\n}\n\n.hero.is-danger .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-danger .subtitle a:not(.button),\n.hero.is-danger .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-danger .navbar-menu {\n    background-color: #f14668;\n  }\n}\n\n.hero.is-danger .navbar-item,\n.hero.is-danger .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-danger a.navbar-item:hover, .hero.is-danger a.navbar-item.is-active,\n.hero.is-danger .navbar-link:hover,\n.hero.is-danger .navbar-link.is-active {\n  background-color: #ef2e55;\n  color: #fff;\n}\n\n.hero.is-danger .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-danger .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-danger .tabs li.is-active a {\n  color: #f14668 !important;\n  opacity: 1;\n}\n\n.hero.is-danger .tabs.is-boxed a, .hero.is-danger .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-danger .tabs.is-boxed a:hover, .hero.is-danger .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-danger .tabs.is-boxed li.is-active a, .hero.is-danger .tabs.is-boxed li.is-active a:hover, .hero.is-danger .tabs.is-toggle li.is-active a, .hero.is-danger .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #f14668;\n}\n\n.hero.is-danger.is-bold {\n  background-image: linear-gradient(141deg, #fa0a62 0%, #f14668 71%, #f7595f 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-danger.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #fa0a62 0%, #f14668 71%, #f7595f 100%);\n  }\n}\n\n.hero.is-small .hero-body {\n  padding: 1.5rem;\n}\n\n@media screen and (min-width: 769px), print {\n  .hero.is-medium .hero-body {\n    padding: 9rem 4.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .hero.is-large .hero-body {\n    padding: 18rem 6rem;\n  }\n}\n\n.hero.is-halfheight .hero-body, .hero.is-fullheight .hero-body, .hero.is-fullheight-with-navbar .hero-body {\n  align-items: center;\n  display: flex;\n}\n\n.hero.is-halfheight .hero-body > .container, .hero.is-fullheight .hero-body > .container, .hero.is-fullheight-with-navbar .hero-body > .container {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.hero.is-halfheight {\n  min-height: 50vh;\n}\n\n.hero.is-fullheight {\n  min-height: 100vh;\n}\n\n.hero-video {\n  overflow: hidden;\n}\n\n.hero-video video {\n  left: 50%;\n  min-height: 100%;\n  min-width: 100%;\n  position: absolute;\n  top: 50%;\n  transform: translate3d(-50%, -50%, 0);\n}\n\n.hero-video.is-transparent {\n  opacity: 0.3;\n}\n\n@media screen and (max-width: 768px) {\n  .hero-video {\n    display: none;\n  }\n}\n\n.hero-buttons {\n  margin-top: 1.5rem;\n}\n\n@media screen and (max-width: 768px) {\n  .hero-buttons .button {\n    display: flex;\n  }\n  .hero-buttons .button:not(:last-child) {\n    margin-bottom: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .hero-buttons {\n    display: flex;\n    justify-content: center;\n  }\n  .hero-buttons .button:not(:last-child) {\n    margin-right: 1.5rem;\n  }\n}\n\n.hero-head,\n.hero-foot {\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.hero-body {\n  flex-grow: 1;\n  flex-shrink: 0;\n  padding: 3rem 1.5rem;\n}\n\n@media screen and (min-width: 769px), print {\n  .hero-body {\n    padding: 3rem 3rem;\n  }\n}\n\n.section {\n  padding: 3rem 1.5rem;\n}\n\n@media screen and (min-width: 1024px) {\n  .section {\n    padding: 3rem 3rem;\n  }\n  .section.is-medium {\n    padding: 9rem 4.5rem;\n  }\n  .section.is-large {\n    padding: 18rem 6rem;\n  }\n}\n\n.footer {\n  background-color: #fafafa;\n  padding: 3rem 1.5rem 6rem;\n}\n/*# sourceMappingURL=bulma.css.map */"
  },
  {
    "path": "examples/counter/assets/favicon/about.txt",
    "content": "This favicon was generated using the following font:\n\n- Font Title: Leckerli One\n- Font Author: Copyright (c) 2011 Gesine Todt (www.gesine-todt.de), with Reserved Font Names \"Leckerli\"\n- Font Source: http://fonts.gstatic.com/s/leckerlione/v16/V8mCoQH8VCsNttEnxnGQ-1itLZxcBtItFw.ttf\n- Font License: SIL Open Font License, 1.1 (http://scripts.sil.org/OFL))\n"
  },
  {
    "path": "examples/counter/assets/favicon/site.webmanifest",
    "content": "{\"name\":\"\",\"short_name\":\"\",\"icons\":[{\"src\":\"/assets/favicon/android-chrome-192x192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\"},{\"src\":\"/assets/favicon/android-chrome-512x512.png\",\"sizes\":\"512x512\",\"type\":\"image/png\"}],\"theme_color\":\"#ffffff\",\"background_color\":\"#ffffff\",\"display\":\"standalone\"}\n"
  },
  {
    "path": "examples/counter/cdk/.gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# go.sum should be committed\n!go.sum\n\n# CDK asset staging directory\n.cdk.staging\ncdk.out\n"
  },
  {
    "path": "examples/counter/cdk/cdk.json",
    "content": "{\n  \"app\": \"go mod download && go run stack.go\",\n  \"watch\": {\n    \"include\": [\n      \"**\"\n    ],\n    \"exclude\": [\n      \"README.md\",\n      \"cdk*.json\",\n      \"go.mod\",\n      \"go.sum\",\n      \"**/*test.go\"\n    ]\n  },\n  \"context\": {\n    \"@aws-cdk/aws-lambda:recognizeLayerVersion\": true,\n    \"@aws-cdk/core:checkSecretUsage\": true,\n    \"@aws-cdk/core:target-partitions\": [\n      \"aws\",\n      \"aws-cn\"\n    ],\n    \"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver\": true,\n    \"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName\": true,\n    \"@aws-cdk/aws-ecs:arnFormatIncludesClusterName\": true,\n    \"@aws-cdk/aws-iam:minimizePolicies\": true,\n    \"@aws-cdk/core:validateSnapshotRemovalPolicy\": true,\n    \"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName\": true,\n    \"@aws-cdk/aws-s3:createDefaultLoggingPolicy\": true,\n    \"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption\": true,\n    \"@aws-cdk/aws-apigateway:disableCloudWatchRole\": true,\n    \"@aws-cdk/core:enablePartitionLiterals\": true,\n    \"@aws-cdk/aws-events:eventsTargetQueueSameAccount\": true,\n    \"@aws-cdk/aws-iam:standardizedServicePrincipals\": true,\n    \"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker\": true,\n    \"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName\": true,\n    \"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy\": true,\n    \"@aws-cdk/aws-route53-patters:useCertificate\": true,\n    \"@aws-cdk/customresources:installLatestAwsSdkDefault\": false,\n    \"@aws-cdk/aws-rds:databaseProxyUniqueResourceName\": true,\n    \"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup\": true,\n    \"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId\": true,\n    \"@aws-cdk/aws-ec2:launchTemplateDefaultUserData\": true,\n    \"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments\": true,\n    \"@aws-cdk/aws-redshift:columnId\": true,\n    \"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2\": true\n  }\n}\n"
  },
  {
    "path": "examples/counter/cdk/stack.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/aws/aws-cdk-go/awscdk/v2\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awscloudfront\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awscloudfrontorigins\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awsdynamodb\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awsiam\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awslambda\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awss3\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awss3deployment\"\n\tawslambdago \"github.com/aws/aws-cdk-go/awscdklambdagoalpha/v2\"\n\t\"github.com/aws/constructs-go/constructs/v10\"\n\t\"github.com/aws/jsii-runtime-go\"\n)\n\ntype CounterStackProps struct {\n\tawscdk.StackProps\n}\n\nfunc NewCounterStack(scope constructs.Construct, id string, props *CounterStackProps) awscdk.Stack {\n\tvar sprops awscdk.StackProps\n\tif props != nil {\n\t\tsprops = props.StackProps\n\t}\n\tstack := awscdk.NewStack(scope, &id, &sprops)\n\n\t// Create a global count database.\n\tdb := awsdynamodb.NewTable(stack, jsii.String(\"count\"), &awsdynamodb.TableProps{\n\t\tPartitionKey: &awsdynamodb.Attribute{\n\t\t\tName: jsii.String(\"_pk\"),\n\t\t\tType: awsdynamodb.AttributeType_STRING,\n\t\t},\n\t\tBillingMode: awsdynamodb.BillingMode_PAY_PER_REQUEST,\n\t\t// Change this for production systems.\n\t\tRemovalPolicy:       awscdk.RemovalPolicy_DESTROY,\n\t\tTimeToLiveAttribute: jsii.String(\"_ttl\"),\n\t})\n\n\t// Strip the binary, and remove the deprecated Lambda SDK RPC code for performance.\n\t// These options are not required, but make cold start faster.\n\tbundlingOptions := &awslambdago.BundlingOptions{\n\t\tGoBuildFlags: &[]*string{jsii.String(`-ldflags \"-s -w\" -tags lambda.norpc`)},\n\t}\n\tf := awslambdago.NewGoFunction(stack, jsii.String(\"handler\"), &awslambdago.GoFunctionProps{\n\t\tRuntime:      awslambda.Runtime_PROVIDED_AL2(),\n\t\tMemorySize:   jsii.Number(1024),\n\t\tArchitecture: awslambda.Architecture_ARM_64(),\n\t\tEntry:        jsii.String(\"../lambda\"),\n\t\tBundling:     bundlingOptions,\n\t\tEnvironment: &map[string]*string{\n\t\t\t\"TABLE_NAME\": db.TableName(),\n\t\t},\n\t})\n\t// Grant DB access.\n\tdb.GrantReadWriteData(f)\n\t// Add a Function URL.\n\tlambdaURL := f.AddFunctionUrl(&awslambda.FunctionUrlOptions{\n\t\tAuthType: awslambda.FunctionUrlAuthType_NONE,\n\t})\n\tawscdk.NewCfnOutput(stack, jsii.String(\"lambdaFunctionUrl\"), &awscdk.CfnOutputProps{\n\t\tExportName: jsii.String(\"lambdaFunctionUrl\"),\n\t\tValue:      lambdaURL.Url(),\n\t})\n\n\tassetsBucket := awss3.NewBucket(stack, jsii.String(\"assets\"), &awss3.BucketProps{\n\t\tBlockPublicAccess: awss3.BlockPublicAccess_BLOCK_ALL(),\n\t\tEncryption:        awss3.BucketEncryption_S3_MANAGED,\n\t\tEnforceSSL:        jsii.Bool(true),\n\t\tRemovalPolicy:     awscdk.RemovalPolicy_DESTROY,\n\t\tVersioned:         jsii.Bool(false),\n\t})\n\t// Allow CloudFront to read from the bucket.\n\tcfOAI := awscloudfront.NewOriginAccessIdentity(stack, jsii.String(\"cfnOriginAccessIdentity\"), &awscloudfront.OriginAccessIdentityProps{})\n\tcfs := awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{})\n\tcfs.AddActions(jsii.String(\"s3:GetBucket*\"))\n\tcfs.AddActions(jsii.String(\"s3:GetObject*\"))\n\tcfs.AddActions(jsii.String(\"s3:List*\"))\n\tcfs.AddResources(assetsBucket.BucketArn())\n\tcfs.AddResources(jsii.String(fmt.Sprintf(\"%v/*\", *assetsBucket.BucketArn())))\n\tcfs.AddCanonicalUserPrincipal(cfOAI.CloudFrontOriginAccessIdentityS3CanonicalUserId())\n\tassetsBucket.AddToResourcePolicy(cfs)\n\n\t// Add a CloudFront distribution to route between the public directory and the Lambda function URL.\n\tlambdaURLDomain := awscdk.Fn_Select(jsii.Number(2), awscdk.Fn_Split(jsii.String(\"/\"), lambdaURL.Url(), nil))\n\tlambdaOrigin := awscloudfrontorigins.NewHttpOrigin(lambdaURLDomain, &awscloudfrontorigins.HttpOriginProps{\n\t\tProtocolPolicy: awscloudfront.OriginProtocolPolicy_HTTPS_ONLY,\n\t})\n\tcf := awscloudfront.NewDistribution(stack, jsii.String(\"customerFacing\"), &awscloudfront.DistributionProps{\n\t\tDefaultBehavior: &awscloudfront.BehaviorOptions{\n\t\t\tAllowedMethods:       awscloudfront.AllowedMethods_ALLOW_ALL(),\n\t\t\tOrigin:               lambdaOrigin,\n\t\t\tCachedMethods:        awscloudfront.CachedMethods_CACHE_GET_HEAD(),\n\t\t\tOriginRequestPolicy:  awscloudfront.OriginRequestPolicy_ALL_VIEWER_EXCEPT_HOST_HEADER(),\n\t\t\tCachePolicy:          awscloudfront.CachePolicy_CACHING_DISABLED(),\n\t\t\tViewerProtocolPolicy: awscloudfront.ViewerProtocolPolicy_REDIRECT_TO_HTTPS,\n\t\t},\n\t\tPriceClass: awscloudfront.PriceClass_PRICE_CLASS_100,\n\t})\n\n\t// Add /assets* to the distribution backed by S3.\n\tassetsOrigin := awscloudfrontorigins.NewS3Origin(assetsBucket, &awscloudfrontorigins.S3OriginProps{\n\t\t// Get content from the / directory in the bucket.\n\t\tOriginPath:           jsii.String(\"/\"),\n\t\tOriginAccessIdentity: cfOAI,\n\t})\n\tcf.AddBehavior(jsii.String(\"/assets*\"), assetsOrigin, nil)\n\n\t// Export the domain.\n\tawscdk.NewCfnOutput(stack, jsii.String(\"cloudFrontDomain\"), &awscdk.CfnOutputProps{\n\t\tExportName: jsii.String(\"cloudfrontDomain\"),\n\t\tValue:      cf.DomainName(),\n\t})\n\n\t// Deploy the contents of the ./assets directory to the S3 bucket.\n\tawss3deployment.NewBucketDeployment(stack, jsii.String(\"assetsDeployment\"), &awss3deployment.BucketDeploymentProps{\n\t\tDestinationBucket: assetsBucket,\n\t\tSources: &[]awss3deployment.ISource{\n\t\t\tawss3deployment.Source_Asset(jsii.String(\"../assets\"), nil),\n\t\t},\n\t\tDestinationKeyPrefix: jsii.String(\"assets\"),\n\t\tDistribution:         cf,\n\t\tDistributionPaths:    jsii.Strings(\"/assets*\"),\n\t})\n\n\treturn stack\n}\n\nfunc main() {\n\tdefer jsii.Close()\n\tapp := awscdk.NewApp(nil)\n\tNewCounterStack(app, \"CounterStack\", &CounterStackProps{})\n\tapp.Synth(nil)\n}\n"
  },
  {
    "path": "examples/counter/components/components.templ",
    "content": "package components\n\nimport \"strconv\"\n\ncss border() {\n\tborder: 1px solid #eeeeee;\n\tborder-radius: 4px;\n\tmargin: 10px;\n\tpadding-top: 30px;\n\tpadding-bottom: 30px;\n}\n\ntempl counts(global, session int) {\n\t<form id=\"countsForm\" action=\"/\" method=\"POST\" hx-post=\"/\" hx-select=\"#countsForm\" hx-swap=\"outerHTML\">\n\t\t<div class=\"columns\">\n\t\t\t<div class={ \"column\", \"has-text-centered\", \"is-primary\", border }>\n\t\t\t\t<h1 class=\"title is-size-1 has-text-centered\">{ strconv.Itoa(global) }</h1>\n\t\t\t\t<p class=\"subtitle has-text-centered\">Global</p>\n\t\t\t\t<div><button class=\"button is-primary\" type=\"submit\" name=\"global\" value=\"global\">+1</button></div>\n\t\t\t</div>\n\t\t\t<div class={ \"column\", \"has-text-centered\", border }>\n\t\t\t\t<h1 class=\"title is-size-1 has-text-centered\">{ strconv.Itoa(session) }</h1>\n\t\t\t\t<p class=\"subtitle has-text-centered\">Session</p>\n\t\t\t\t<div><button class=\"button is-secondary\" type=\"submit\" name=\"session\" value=\"session\">+1</button></div>\n\t\t\t</div>\n\t\t</div>\n\t</form>\n}\n\ntempl Page(global, session int) {\n\t<html>\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<title>Counts</title>\n\t\t\t<link rel=\"stylesheet\" href=\"/assets/css/bulma.min.css\"/>\n\t\t\t<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/assets/favicon/apple-touch-icon.png\"/>\n\t\t\t<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/assets/favicon/favicon-32x32.png\"/>\n\t\t\t<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/assets/favicon/favicon-16x16.png\"/>\n\t\t\t<link rel=\"manifest\" href=\"/assets/favicon/site.webmanifest\"/>\n\t\t\t<script src=\"/assets/js/htmx.min.js\"></script>\n\t\t</head>\n\t\t<body class=\"bg-gray-100\">\n\t\t\t<header class=\"hero is-primary\">\n\t\t\t\t<div class=\"hero-body\">\n\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t<h1 class=\"title\">Counts</h1>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</header>\n\t\t\t<section class=\"section\">\n\t\t\t\t<div class=\"container\">\n\t\t\t\t\t<div class=\"columns is-centered\">\n\t\t\t\t\t\t<div class=\"column is-half\">\n\t\t\t\t\t\t\t@counts(global, session)\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/counter/components/components_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage components\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"strconv\"\n\nfunc border() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`border:1px solid #eeeeee;`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(`border-radius:4px;`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(`margin:10px;`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(`padding-top:30px;`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(`padding-bottom:30px;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`border`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc counts(global, session int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<form id=\\\"countsForm\\\" action=\\\"/\\\" method=\\\"POST\\\" hx-post=\\\"/\\\" hx-select=\\\"#countsForm\\\" hx-swap=\\\"outerHTML\\\"><div class=\\\"columns\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 = []any{\"column\", \"has-text-centered\", \"is-primary\", border}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/counter/components/components.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\"><h1 class=\\\"title is-size-1 has-text-centered\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(global))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/counter/components/components.templ`, Line: 17, Col: 72}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</h1><p class=\\\"subtitle has-text-centered\\\">Global</p><div><button class=\\\"button is-primary\\\" type=\\\"submit\\\" name=\\\"global\\\" value=\\\"global\\\">+1</button></div></div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 = []any{\"column\", \"has-text-centered\", border}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 string\n\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var5).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/counter/components/components.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"\\\"><h1 class=\\\"title is-size-1 has-text-centered\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 string\n\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(session))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/counter/components/components.templ`, Line: 22, Col: 73}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"</h1><p class=\\\"subtitle has-text-centered\\\">Session</p><div><button class=\\\"button is-secondary\\\" type=\\\"submit\\\" name=\\\"session\\\" value=\\\"session\\\">+1</button></div></div></div></form>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc Page(global, session int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var8 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var8 == nil {\n\t\t\ttempl_7745c5c3_Var8 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<html><head><meta charset=\\\"UTF-8\\\"><meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"><title>Counts</title><link rel=\\\"stylesheet\\\" href=\\\"/assets/css/bulma.min.css\\\"><link rel=\\\"apple-touch-icon\\\" sizes=\\\"180x180\\\" href=\\\"/assets/favicon/apple-touch-icon.png\\\"><link rel=\\\"icon\\\" type=\\\"image/png\\\" sizes=\\\"32x32\\\" href=\\\"/assets/favicon/favicon-32x32.png\\\"><link rel=\\\"icon\\\" type=\\\"image/png\\\" sizes=\\\"16x16\\\" href=\\\"/assets/favicon/favicon-16x16.png\\\"><link rel=\\\"manifest\\\" href=\\\"/assets/favicon/site.webmanifest\\\"><script src=\\\"/assets/js/htmx.min.js\\\"></script></head><body class=\\\"bg-gray-100\\\"><header class=\\\"hero is-primary\\\"><div class=\\\"hero-body\\\"><div class=\\\"container\\\"><h1 class=\\\"title\\\">Counts</h1></div></div></header><section class=\\\"section\\\"><div class=\\\"container\\\"><div class=\\\"columns is-centered\\\"><div class=\\\"column is-half\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = counts(global, session).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"</div></div></div></section></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/counter/db/db.go",
    "content": "package db\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/aws/aws-sdk-go-v2/aws\"\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue\"\n\t\"github.com/aws/aws-sdk-go-v2/service/dynamodb\"\n\t\"github.com/aws/aws-sdk-go-v2/service/dynamodb/types\"\n)\n\ntype OptionsFunc func(*CountStore)\n\nfunc WithClient(client *dynamodb.Client) func(*CountStore) {\n\treturn func(ms *CountStore) {\n\t\tms.db = client\n\t}\n}\n\nfunc NewCountStore(tableName, region string, options ...OptionsFunc) (s *CountStore, err error) {\n\ts = &CountStore{\n\t\ttableName: tableName,\n\t}\n\tfor _, o := range options {\n\t\to(s)\n\t}\n\tif s.db == nil {\n\t\tcfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(region))\n\t\tif err != nil {\n\t\t\treturn s, err\n\t\t}\n\t\ts.db = dynamodb.NewFromConfig(cfg)\n\t}\n\treturn\n}\n\ntype CountStore struct {\n\tdb        *dynamodb.Client\n\ttableName string\n}\n\nfunc stripEmpty(strings []string) (op []string) {\n\tfor _, s := range strings {\n\t\tif s != \"\" {\n\t\t\top = append(op, s)\n\t\t}\n\t}\n\treturn\n}\n\ntype countRecord struct {\n\tPK    string `dynamodbav:\"_pk\"`\n\tCount int    `dynamodbav:\"count\"`\n}\n\nfunc (s CountStore) BatchGet(ctx context.Context, ids ...string) (counts []int, err error) {\n\tnonEmptyIDs := stripEmpty(ids)\n\tif len(nonEmptyIDs) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Make DynamoDB keys.\n\tris := make(map[string]types.KeysAndAttributes)\n\tfor _, id := range nonEmptyIDs {\n\t\tri := ris[s.tableName]\n\t\tri.Keys = append(ris[s.tableName].Keys, map[string]types.AttributeValue{\n\t\t\t\"_pk\": &types.AttributeValueMemberS{\n\t\t\t\tValue: id,\n\t\t\t},\n\t\t})\n\t\tri.ConsistentRead = aws.Bool(true)\n\t\tris[s.tableName] = ri\n\t}\n\n\t// Execute the batch request.\n\tvar batchResponses []map[string]types.AttributeValue\n\n\t// DynamoDB might not process everything, so we need a loop.\n\tvar unprocessedAttempts int\n\tfor {\n\t\tvar bgio *dynamodb.BatchGetItemOutput\n\t\tbgio, err = s.db.BatchGetItem(ctx, &dynamodb.BatchGetItemInput{\n\t\t\tRequestItems: ris,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tfor _, responses := range bgio.Responses {\n\t\t\tbatchResponses = append(batchResponses, responses...)\n\t\t}\n\t\tif len(bgio.UnprocessedKeys) > 0 {\n\t\t\tris = bgio.UnprocessedKeys\n\t\t\tunprocessedAttempts++\n\t\t\tif unprocessedAttempts > 3 {\n\t\t\t\terr = fmt.Errorf(\"countstore: exceeded three attempts to get all counts\")\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tbreak\n\t}\n\n\t// Process the responses into structs.\n\tcrs := []countRecord{}\n\terr = attributevalue.UnmarshalListOfMaps(batchResponses, &crs)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"countstore: failed to unmarshal result of BatchGet: %w\", err)\n\t\treturn\n\t}\n\n\t// Match up the inputs to the records.\n\tidToCount := make(map[string]int, len(ids))\n\tfor _, cr := range crs {\n\t\tidToCount[cr.PK] = cr.Count\n\t}\n\n\t// Create the output in the right order.\n\t// Missing values are defaulted to zero.\n\tfor _, id := range ids {\n\t\tcounts = append(counts, idToCount[id])\n\t}\n\n\treturn\n}\n\nfunc (s CountStore) Get(ctx context.Context, id string) (count int, err error) {\n\tif id == \"\" {\n\t\treturn\n\t}\n\tgio, err := s.db.GetItem(ctx, &dynamodb.GetItemInput{\n\t\tKey: map[string]types.AttributeValue{\n\t\t\t\"_pk\": &types.AttributeValueMemberS{\n\t\t\t\tValue: id,\n\t\t\t},\n\t\t},\n\t\tTableName:      &s.tableName,\n\t\tConsistentRead: aws.Bool(true),\n\t})\n\tif err != nil || gio.Item == nil {\n\t\treturn\n\t}\n\n\tvar cr countRecord\n\terr = attributevalue.UnmarshalMap(gio.Item, &cr)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"countstore: failed to process result of Get: %w\", err)\n\t}\n\tcount = cr.Count\n\n\treturn\n}\n\nfunc (s CountStore) Increment(ctx context.Context, id string) (count int, err error) {\n\tif id == \"\" {\n\t\treturn\n\t}\n\tuio, err := s.db.UpdateItem(ctx, &dynamodb.UpdateItemInput{\n\t\tKey: map[string]types.AttributeValue{\n\t\t\t\"_pk\": &types.AttributeValueMemberS{\n\t\t\t\tValue: id,\n\t\t\t},\n\t\t},\n\t\tTableName:        &s.tableName,\n\t\tUpdateExpression: aws.String(\"SET #c = if_not_exists(#c, :zero) + :one\"),\n\t\tExpressionAttributeNames: map[string]string{\n\t\t\t\"#c\": \"count\",\n\t\t},\n\t\tExpressionAttributeValues: map[string]types.AttributeValue{\n\t\t\t\":zero\": &types.AttributeValueMemberN{Value: \"0\"},\n\t\t\t\":one\":  &types.AttributeValueMemberN{Value: \"1\"},\n\t\t},\n\t\tReturnValues: types.ReturnValueAllNew,\n\t})\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// Parse the response.\n\tvar cr countRecord\n\terr = attributevalue.UnmarshalMap(uio.Attributes, &cr)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"countstore: failed to process result of Increment: %w\", err)\n\t}\n\tcount = cr.Count\n\n\treturn\n}\n"
  },
  {
    "path": "examples/counter/go.mod",
    "content": "module github.com/a-h/templ/examples/counter\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.234-0.20230427112944-80f0dc03a8a8\n\tgithub.com/akrylysov/algnhsa v1.1.0\n\tgithub.com/aws/aws-cdk-go/awscdk/v2 v2.147.3\n\tgithub.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.147.3-alpha.0\n\tgithub.com/aws/aws-sdk-go-v2 v1.30.1\n\tgithub.com/aws/aws-sdk-go-v2/config v1.27.24\n\tgithub.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.7\n\tgithub.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.1\n\tgithub.com/aws/constructs-go/constructs/v10 v10.3.0\n\tgithub.com/aws/jsii-runtime-go v1.101.0\n\tgithub.com/segmentio/ksuid v1.0.4\n\tgolang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8\n)\n\nrequire (\n\tgithub.com/Masterminds/semver/v3 v3.2.1 // indirect\n\tgithub.com/aws/aws-lambda-go v1.47.0 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/credentials v1.17.24 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.22.1 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.14 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect\n\tgithub.com/aws/smithy-go v1.20.3 // indirect\n\tgithub.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.202 // indirect\n\tgithub.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2 // indirect\n\tgithub.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.3 // indirect\n\tgithub.com/fatih/color v1.17.0 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.0 // indirect\n\tgithub.com/mattn/go-colorable v0.1.13 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/yuin/goldmark v1.7.4 // indirect\n\tgolang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect\n\tgolang.org/x/mod v0.26.0 // indirect\n\tgolang.org/x/sync v0.16.0 // indirect\n\tgolang.org/x/sys v0.41.0 // indirect\n\tgolang.org/x/tools v0.35.0 // indirect\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/counter/go.sum",
    "content": "github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=\ngithub.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=\ngithub.com/akrylysov/algnhsa v1.1.0 h1:G0SoP16tMRyiism7VNc3JFA0wq/cVgEkp/ExMVnc6PQ=\ngithub.com/akrylysov/algnhsa v1.1.0/go.mod h1:+bOweRs/WBu5awl+ifCoSYAuKVPAmoTk8XOMrZ1xwiw=\ngithub.com/aws/aws-cdk-go/awscdk/v2 v2.147.3 h1:7Wbi5d1f+RGn6fg9YzzMjD5D/rc/62zuFOtmJIed+B0=\ngithub.com/aws/aws-cdk-go/awscdk/v2 v2.147.3/go.mod h1:WF3lt7ah4wNktbClICIBbKdITtCqyCrPBQl3nkaLug4=\ngithub.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.147.3-alpha.0 h1:j+eT+oCMXTQZL+9ERI1FBDxkFApHPZTYZhtj9zalvlo=\ngithub.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.147.3-alpha.0/go.mod h1:uUP2KJ0yXDOlAl5VmSN36cSpw5Ajv10JVhPl1M7WJ6A=\ngithub.com/aws/aws-lambda-go v1.47.0 h1:0H8s0vumYx/YKs4sE7YM0ktwL2eWse+kfopsRI1sXVI=\ngithub.com/aws/aws-lambda-go v1.47.0/go.mod h1:dpMpZgvWx5vuQJfBt0zqBha60q7Dd7RfgJv23DymV8A=\ngithub.com/aws/aws-sdk-go-v2 v1.30.1 h1:4y/5Dvfrhd1MxRDD77SrfsDaj8kUkkljU7XE83NPV+o=\ngithub.com/aws/aws-sdk-go-v2 v1.30.1/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc=\ngithub.com/aws/aws-sdk-go-v2/config v1.27.24 h1:NM9XicZ5o1CBU/MZaHwFtimRpWx9ohAUAqkG6AqSqPo=\ngithub.com/aws/aws-sdk-go-v2/config v1.27.24/go.mod h1:aXzi6QJTuQRVVusAO8/NxpdTeTyr/wRcybdDtfUwJSs=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.24 h1:YclAsrnb1/GTQNt2nzv+756Iw4mF8AOzcDfweWwwm/M=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.17.24/go.mod h1:Hld7tmnAkoBQdTMNYZGzztzKRdA4fCdn9L83LOoigac=\ngithub.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.7 h1:pPhmvNKbgb9l5VHcPmMx9g+FHtRbY+ba2J6GefXQGEI=\ngithub.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.7/go.mod h1:OZU7QRvIYXhKry99PttkDTQyN8yCo8RzYjhIKHdQXoo=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/lQRMaIpJkLLaJ1ZI76no=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 h1:5SAoZ4jYpGH4721ZNoS1znQrhOfZinOhc4XuTXx/nVc=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13/go.mod h1:+rdA6ZLpaSeM7tSg/B0IEDinCIBJGmW8rKDFkYpP04g=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 h1:WIijqeaAO7TYFLbhsZmi2rgLEAtWOC1LhxCAVTJlSKw=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13/go.mod h1:i+kbfa76PQbWw/ULoWnp51EYVWH4ENln76fLQE3lXT8=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=\ngithub.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.1 h1:Szwz1vpZkvfhFMJ0X5uUECgHeUmPAxk1UGqAVs/pARw=\ngithub.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.1/go.mod h1:b4wouGyJlzkr2HAvPrDGgYNp1EtmlXOkzhEOvl0c0FQ=\ngithub.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.22.1 h1:jfkCLx62YWL6bSOkT7aEDKNAX3OwWomlThCxQNBPvbY=\ngithub.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.22.1/go.mod h1:dLPiMfhRZhblwOeKqdNde7K9jl/pMuIGCGAwC6vQOIo=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI=\ngithub.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.14 h1:X1J0Kd17n1PeXeoArNXlvnKewCyMvhVQh7iNMy6oi3s=\ngithub.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.9.14/go.mod h1:VYMN7l7dxp6xtQRjqIau6d7QAbmPG+yJ75GtCy70f18=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 h1:I9zMeF107l0rJrpnHpjEiiTSCKYAIw8mALiXcPsGBiA=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15/go.mod h1:9xWJ3Q/S6Ojusz1UIkfycgD1mGirJfLLKqq3LPT7WN8=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 h1:ORnrOK0C4WmYV/uYt3koHEWBLYsRDwk2Np+eEoyV4Z0=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ=\ngithub.com/aws/constructs-go/constructs/v10 v10.3.0 h1:LsjBIMiaDX/vqrXWhzTquBJ9pPdi02/H+z1DCwg0PEM=\ngithub.com/aws/constructs-go/constructs/v10 v10.3.0/go.mod h1:GgzwIwoRJ2UYsr3SU+JhAl+gq5j39bEMYf8ev3J+s9s=\ngithub.com/aws/jsii-runtime-go v1.101.0 h1:x4rWNWRz7uDhVN0qSO7T6cG0VAhQ9300s5DjWUrXmWY=\ngithub.com/aws/jsii-runtime-go v1.101.0/go.mod h1:4L4Qmve/HSwM5hXV5ZowR2gBNb9zqkUtycaaN6aZ3mg=\ngithub.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=\ngithub.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=\ngithub.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.202 h1:VixXB9DnHN8oP7pXipq8GVFPjWCOdeNxIaS/ZyUwTkI=\ngithub.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.202/go.mod h1:iPUti/SWjA3XAS3CpnLciFjS8TN9Y+8mdZgDfSgcyus=\ngithub.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2 h1:k+WD+6cERd59Mao84v0QtRrcdZuuSMfzlEmuIypKnVs=\ngithub.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2/go.mod h1:CvFHBo0qcg8LUkJqIxQtP1rD/sNGv9bX3L2vHT2FUAo=\ngithub.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.3 h1:8NLWOIVaxAtpUXv5reojlAeDP7R8yswm9mDONf7F/3o=\ngithub.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.3/go.mod h1:ZjFqfhYpCLzh4z7ChcHCrkXfqCuEiRlNApDfJd6plts=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=\ngithub.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=\ngithub.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=\ngithub.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=\ngolang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=\ngolang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=\ngolang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=\ngolang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=\ngolang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "examples/counter/handlers/default.go",
    "content": "package handlers\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ/examples/counter/components\"\n\t\"github.com/a-h/templ/examples/counter/services\"\n\t\"github.com/a-h/templ/examples/counter/session\"\n\t\"golang.org/x/exp/slog\"\n)\n\ntype CountService interface {\n\tIncrement(ctx context.Context, it services.IncrementType, sessionID string) (counts services.Counts, err error)\n\tGet(ctx context.Context, sessionID string) (counts services.Counts, err error)\n}\n\nfunc New(log *slog.Logger, cs CountService) *DefaultHandler {\n\treturn &DefaultHandler{\n\t\tLog:          log,\n\t\tCountService: cs,\n\t}\n}\n\ntype DefaultHandler struct {\n\tLog          *slog.Logger\n\tCountService CountService\n}\n\nfunc (h *DefaultHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif r.Method == http.MethodPost {\n\t\th.Post(w, r)\n\t\treturn\n\t}\n\th.Get(w, r)\n}\n\nfunc (h *DefaultHandler) Get(w http.ResponseWriter, r *http.Request) {\n\tvar props ViewProps\n\tvar err error\n\tprops.Counts, err = h.CountService.Get(r.Context(), session.ID(r))\n\tif err != nil {\n\t\th.Log.Error(\"failed to get counts\", slog.Any(\"error\", err))\n\t\thttp.Error(w, \"failed to get counts\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\th.View(w, r, props)\n}\n\nfunc (h *DefaultHandler) Post(w http.ResponseWriter, r *http.Request) {\n\tr.ParseForm()\n\n\t// Decide the action to take based on the button that was pressed.\n\tvar it services.IncrementType\n\tif r.Form.Has(\"global\") {\n\t\tit = services.IncrementTypeGlobal\n\t}\n\tif r.Form.Has(\"session\") {\n\t\tit = services.IncrementTypeSession\n\t}\n\n\tcounts, err := h.CountService.Increment(r.Context(), it, session.ID(r))\n\tif err != nil {\n\t\th.Log.Error(\"failed to increment\", slog.Any(\"error\", err))\n\t\thttp.Error(w, \"failed to increment\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\t// Display the view.\n\th.View(w, r, ViewProps{\n\t\tCounts: counts,\n\t})\n}\n\ntype ViewProps struct {\n\tCounts services.Counts\n}\n\nfunc (h *DefaultHandler) View(w http.ResponseWriter, r *http.Request, props ViewProps) {\n\tcomponents.Page(props.Counts.Global, props.Counts.Session).Render(r.Context(), w)\n}\n"
  },
  {
    "path": "examples/counter/lambda/main.go",
    "content": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/a-h/templ/examples/counter/db\"\n\t\"github.com/a-h/templ/examples/counter/handlers\"\n\t\"github.com/a-h/templ/examples/counter/services\"\n\t\"github.com/a-h/templ/examples/counter/session\"\n\t\"github.com/akrylysov/algnhsa\"\n\t\"golang.org/x/exp/slog\"\n)\n\nfunc main() {\n\t// Create handlers.\n\tlog := slog.New(slog.NewJSONHandler(os.Stderr, nil))\n\ts, err := db.NewCountStore(os.Getenv(\"TABLE_NAME\"), os.Getenv(\"AWS_REGION\"))\n\tif err != nil {\n\t\tlog.Error(\"failed to create store\", slog.Any(\"error\", err))\n\t\tos.Exit(1)\n\t}\n\tcs := services.NewCount(log, s)\n\th := handlers.New(log, cs)\n\n\t// Add session middleware.\n\tsh := session.NewMiddleware(h)\n\n\t// Start Lambda.\n\talgnhsa.ListenAndServe(sh, nil)\n}\n"
  },
  {
    "path": "examples/counter/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/examples/counter/db\"\n\t\"github.com/a-h/templ/examples/counter/handlers\"\n\t\"github.com/a-h/templ/examples/counter/services\"\n\t\"github.com/a-h/templ/examples/counter/session\"\n\t\"golang.org/x/exp/slog\"\n)\n\nfunc main() {\n\tlog := slog.New(slog.NewJSONHandler(os.Stderr, nil))\n\ts, err := db.NewCountStore(os.Getenv(\"TABLE_NAME\"), os.Getenv(\"AWS_REGION\"))\n\tif err != nil {\n\t\tlog.Error(\"failed to create store\", slog.Any(\"error\", err))\n\t\tos.Exit(1)\n\t}\n\tcs := services.NewCount(log, s)\n\th := handlers.New(log, cs)\n\n\tvar secureFlag = true\n\tif os.Getenv(\"SECURE_FLAG\") == \"false\" {\n\t\tsecureFlag = false\n\t}\n\n\t// Add session middleware.\n\tsh := session.NewMiddleware(h, session.WithSecure(secureFlag))\n\n\tserver := &http.Server{\n\t\tAddr:         \"localhost:9000\",\n\t\tHandler:      sh,\n\t\tReadTimeout:  time.Second * 10,\n\t\tWriteTimeout: time.Second * 10,\n\t}\n\n\tfmt.Printf(\"Listening on %v\\n\", server.Addr)\n\tserver.ListenAndServe()\n}\n"
  },
  {
    "path": "examples/counter/services/count.go",
    "content": "package services\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/a-h/templ/examples/counter/db\"\n\t\"golang.org/x/exp/slog\"\n)\n\ntype Counts struct {\n\tGlobal  int\n\tSession int\n}\n\ntype IncrementType int\n\nconst (\n\tIncrementTypeUnknown IncrementType = iota\n\tIncrementTypeGlobal\n\tIncrementTypeSession\n)\n\nvar ErrUnknownIncrementType error = errors.New(\"unknown increment type\")\n\nfunc NewCount(log *slog.Logger, cs *db.CountStore) Count {\n\treturn Count{\n\t\tLog:        log,\n\t\tCountStore: cs,\n\t}\n}\n\ntype Count struct {\n\tLog        *slog.Logger\n\tCountStore *db.CountStore\n}\n\nfunc (cs Count) Increment(ctx context.Context, it IncrementType, sessionID string) (counts Counts, err error) {\n\t// Work out which operations to do.\n\tvar global, session func(ctx context.Context, id string) (count int, err error)\n\tswitch it {\n\tcase IncrementTypeGlobal:\n\t\tglobal = cs.CountStore.Increment\n\t\tsession = cs.CountStore.Get\n\tcase IncrementTypeSession:\n\t\tglobal = cs.CountStore.Get\n\t\tsession = cs.CountStore.Increment\n\tdefault:\n\t\treturn counts, ErrUnknownIncrementType\n\t}\n\n\t// Run the operations in parallel.\n\tvar wg sync.WaitGroup\n\twg.Add(2)\n\terrs := make([]error, 2)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tcounts.Global, errs[0] = global(ctx, \"global\")\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tcounts.Session, errs[1] = session(ctx, sessionID)\n\t}()\n\twg.Wait()\n\n\treturn counts, errors.Join(errs...)\n}\n\nfunc (cs Count) Get(ctx context.Context, sessionID string) (counts Counts, err error) {\n\tglobalAndSessionCounts, err := cs.CountStore.BatchGet(ctx, \"global\", sessionID)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"countservice: failed to get counts: %w\", err)\n\t\treturn\n\t}\n\tif len(globalAndSessionCounts) != 2 {\n\t\terr = fmt.Errorf(\"countservice: unexpected counts returned, expected 2, got %d\", len(globalAndSessionCounts))\n\t\treturn\n\t}\n\tcounts.Global = globalAndSessionCounts[0]\n\tcounts.Session = globalAndSessionCounts[1]\n\treturn\n}\n"
  },
  {
    "path": "examples/counter/session/session.go",
    "content": "package session\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/segmentio/ksuid\"\n)\n\ntype MiddlewareOpts func(*Middleware)\n\nfunc NewMiddleware(next http.Handler, opts ...MiddlewareOpts) http.Handler {\n\tmw := Middleware{\n\t\tNext:     next,\n\t\tSecure:   true,\n\t\tHTTPOnly: true,\n\t}\n\tfor _, opt := range opts {\n\t\topt(&mw)\n\t}\n\treturn mw\n}\n\nfunc WithSecure(secure bool) MiddlewareOpts {\n\treturn func(m *Middleware) {\n\t\tm.Secure = secure\n\t}\n}\n\nfunc WithHTTPOnly(httpOnly bool) MiddlewareOpts {\n\treturn func(m *Middleware) {\n\t\tm.HTTPOnly = httpOnly\n\t}\n}\n\ntype Middleware struct {\n\tNext     http.Handler\n\tSecure   bool\n\tHTTPOnly bool\n}\n\nfunc ID(r *http.Request) (id string) {\n\tcookie, err := r.Cookie(\"sessionID\")\n\tif err != nil {\n\t\treturn\n\t}\n\treturn cookie.Value\n}\n\nfunc (mw Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tid := ID(r)\n\tif id == \"\" {\n\t\tid = ksuid.New().String()\n\t\thttp.SetCookie(w, &http.Cookie{Name: \"sessionID\", Value: id, Secure: mw.Secure, HttpOnly: mw.HTTPOnly})\n\t}\n\tmw.Next.ServeHTTP(w, r)\n}\n"
  },
  {
    "path": "examples/counter-basic/.dockerignore",
    "content": "Dockerfile\n"
  },
  {
    "path": "examples/counter-basic/Dockerfile",
    "content": "# Build.\nFROM golang:1.20 AS build-stage\nWORKDIR /app\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY . /app\nRUN CGO_ENABLED=0 GOOS=linux go build -o /entrypoint\n\n# Deploy.\nFROM gcr.io/distroless/static-debian11 AS release-stage\nWORKDIR /\nCOPY --chown=nonroot --from=build-stage /entrypoint /entrypoint\nCOPY --chown=nonroot --from=build-stage /app/assets /assets\nEXPOSE 8080\nUSER nonroot:nonroot\nENTRYPOINT [\"/entrypoint\"]\n"
  },
  {
    "path": "examples/counter-basic/README.md",
    "content": "## Tasks\n\n### run\n\n```bash\ntempl generate --watch --proxy=\"http://localhost:8080\" --cmd=\"go run .\"\n```\n"
  },
  {
    "path": "examples/counter-basic/assets/bulma.css",
    "content": "/*! bulma.io v0.9.4 | MIT License | github.com/jgthms/bulma */\n/* Bulma Utilities */\n.button, .input, .textarea, .select select, .file-cta,\n.file-name, .pagination-previous,\n.pagination-next,\n.pagination-link,\n.pagination-ellipsis {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  align-items: center;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  box-shadow: none;\n  display: inline-flex;\n  font-size: 1rem;\n  height: 2.5em;\n  justify-content: flex-start;\n  line-height: 1.5;\n  padding-bottom: calc(0.5em - 1px);\n  padding-left: calc(0.75em - 1px);\n  padding-right: calc(0.75em - 1px);\n  padding-top: calc(0.5em - 1px);\n  position: relative;\n  vertical-align: top;\n}\n\n.button:focus, .input:focus, .textarea:focus, .select select:focus, .file-cta:focus,\n.file-name:focus, .pagination-previous:focus,\n.pagination-next:focus,\n.pagination-link:focus,\n.pagination-ellipsis:focus, .is-focused.button, .is-focused.input, .is-focused.textarea, .select select.is-focused, .is-focused.file-cta,\n.is-focused.file-name, .is-focused.pagination-previous,\n.is-focused.pagination-next,\n.is-focused.pagination-link,\n.is-focused.pagination-ellipsis, .button:active, .input:active, .textarea:active, .select select:active, .file-cta:active,\n.file-name:active, .pagination-previous:active,\n.pagination-next:active,\n.pagination-link:active,\n.pagination-ellipsis:active, .is-active.button, .is-active.input, .is-active.textarea, .select select.is-active, .is-active.file-cta,\n.is-active.file-name, .is-active.pagination-previous,\n.is-active.pagination-next,\n.is-active.pagination-link,\n.is-active.pagination-ellipsis {\n  outline: none;\n}\n\n.button[disabled], .input[disabled], .textarea[disabled], .select select[disabled], .file-cta[disabled],\n.file-name[disabled], .pagination-previous[disabled],\n.pagination-next[disabled],\n.pagination-link[disabled],\n.pagination-ellipsis[disabled],\nfieldset[disabled] .button,\nfieldset[disabled] .input,\nfieldset[disabled] .textarea,\nfieldset[disabled] .select select,\n.select fieldset[disabled] select,\nfieldset[disabled] .file-cta,\nfieldset[disabled] .file-name,\nfieldset[disabled] .pagination-previous,\nfieldset[disabled] .pagination-next,\nfieldset[disabled] .pagination-link,\nfieldset[disabled] .pagination-ellipsis {\n  cursor: not-allowed;\n}\n\n.button, .file, .breadcrumb, .pagination-previous,\n.pagination-next,\n.pagination-link,\n.pagination-ellipsis, .tabs, .is-unselectable {\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n\n.select:not(.is-multiple):not(.is-loading)::after, .navbar-link:not(.is-arrowless)::after {\n  border: 3px solid transparent;\n  border-radius: 2px;\n  border-right: 0;\n  border-top: 0;\n  content: \" \";\n  display: block;\n  height: 0.625em;\n  margin-top: -0.4375em;\n  pointer-events: none;\n  position: absolute;\n  top: 50%;\n  transform: rotate(-45deg);\n  transform-origin: center;\n  width: 0.625em;\n}\n\n.box:not(:last-child), .content:not(:last-child), .notification:not(:last-child), .progress:not(:last-child), .table:not(:last-child), .table-container:not(:last-child), .title:not(:last-child),\n.subtitle:not(:last-child), .block:not(:last-child), .breadcrumb:not(:last-child), .level:not(:last-child), .message:not(:last-child), .pagination:not(:last-child), .tabs:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.delete, .modal-close {\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  background-color: rgba(10, 10, 10, 0.2);\n  border: none;\n  border-radius: 9999px;\n  cursor: pointer;\n  pointer-events: auto;\n  display: inline-block;\n  flex-grow: 0;\n  flex-shrink: 0;\n  font-size: 0;\n  height: 20px;\n  max-height: 20px;\n  max-width: 20px;\n  min-height: 20px;\n  min-width: 20px;\n  outline: none;\n  position: relative;\n  vertical-align: top;\n  width: 20px;\n}\n\n.delete::before, .modal-close::before, .delete::after, .modal-close::after {\n  background-color: white;\n  content: \"\";\n  display: block;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translateX(-50%) translateY(-50%) rotate(45deg);\n  transform-origin: center center;\n}\n\n.delete::before, .modal-close::before {\n  height: 2px;\n  width: 50%;\n}\n\n.delete::after, .modal-close::after {\n  height: 50%;\n  width: 2px;\n}\n\n.delete:hover, .modal-close:hover, .delete:focus, .modal-close:focus {\n  background-color: rgba(10, 10, 10, 0.3);\n}\n\n.delete:active, .modal-close:active {\n  background-color: rgba(10, 10, 10, 0.4);\n}\n\n.is-small.delete, .is-small.modal-close {\n  height: 16px;\n  max-height: 16px;\n  max-width: 16px;\n  min-height: 16px;\n  min-width: 16px;\n  width: 16px;\n}\n\n.is-medium.delete, .is-medium.modal-close {\n  height: 24px;\n  max-height: 24px;\n  max-width: 24px;\n  min-height: 24px;\n  min-width: 24px;\n  width: 24px;\n}\n\n.is-large.delete, .is-large.modal-close {\n  height: 32px;\n  max-height: 32px;\n  max-width: 32px;\n  min-height: 32px;\n  min-width: 32px;\n  width: 32px;\n}\n\n.button.is-loading::after, .loader, .select.is-loading::after, .control.is-loading::after {\n  -webkit-animation: spinAround 500ms infinite linear;\n          animation: spinAround 500ms infinite linear;\n  border: 2px solid #dbdbdb;\n  border-radius: 9999px;\n  border-right-color: transparent;\n  border-top-color: transparent;\n  content: \"\";\n  display: block;\n  height: 1em;\n  position: relative;\n  width: 1em;\n}\n\n.image.is-square img,\n.image.is-square .has-ratio, .image.is-1by1 img,\n.image.is-1by1 .has-ratio, .image.is-5by4 img,\n.image.is-5by4 .has-ratio, .image.is-4by3 img,\n.image.is-4by3 .has-ratio, .image.is-3by2 img,\n.image.is-3by2 .has-ratio, .image.is-5by3 img,\n.image.is-5by3 .has-ratio, .image.is-16by9 img,\n.image.is-16by9 .has-ratio, .image.is-2by1 img,\n.image.is-2by1 .has-ratio, .image.is-3by1 img,\n.image.is-3by1 .has-ratio, .image.is-4by5 img,\n.image.is-4by5 .has-ratio, .image.is-3by4 img,\n.image.is-3by4 .has-ratio, .image.is-2by3 img,\n.image.is-2by3 .has-ratio, .image.is-3by5 img,\n.image.is-3by5 .has-ratio, .image.is-9by16 img,\n.image.is-9by16 .has-ratio, .image.is-1by2 img,\n.image.is-1by2 .has-ratio, .image.is-1by3 img,\n.image.is-1by3 .has-ratio, .modal, .modal-background, .is-overlay, .hero-video {\n  bottom: 0;\n  left: 0;\n  position: absolute;\n  right: 0;\n  top: 0;\n}\n\n.navbar-burger {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n  background: none;\n  border: none;\n  color: currentColor;\n  font-family: inherit;\n  font-size: 1em;\n  margin: 0;\n  padding: 0;\n}\n\n/* Bulma Base */\n/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */\nhtml,\nbody,\np,\nol,\nul,\nli,\ndl,\ndt,\ndd,\nblockquote,\nfigure,\nfieldset,\nlegend,\ntextarea,\npre,\niframe,\nhr,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  margin: 0;\n  padding: 0;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  font-size: 100%;\n  font-weight: normal;\n}\n\nul {\n  list-style: none;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n}\n\nhtml {\n  box-sizing: border-box;\n}\n\n*, *::before, *::after {\n  box-sizing: inherit;\n}\n\nimg,\nvideo {\n  height: auto;\n  max-width: 100%;\n}\n\niframe {\n  border: 0;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n\ntd:not([align]),\nth:not([align]) {\n  text-align: inherit;\n}\n\nhtml {\n  background-color: white;\n  font-size: 16px;\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  min-width: 300px;\n  overflow-x: hidden;\n  overflow-y: scroll;\n  text-rendering: optimizeLegibility;\n  -webkit-text-size-adjust: 100%;\n     -moz-text-size-adjust: 100%;\n          text-size-adjust: 100%;\n}\n\narticle,\naside,\nfigure,\nfooter,\nheader,\nhgroup,\nsection {\n  display: block;\n}\n\nbody,\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif;\n}\n\ncode,\npre {\n  -moz-osx-font-smoothing: auto;\n  -webkit-font-smoothing: auto;\n  font-family: monospace;\n}\n\nbody {\n  color: #4a4a4a;\n  font-size: 1em;\n  font-weight: 400;\n  line-height: 1.5;\n}\n\na {\n  color: #485fc7;\n  cursor: pointer;\n  text-decoration: none;\n}\n\na strong {\n  color: currentColor;\n}\n\na:hover {\n  color: #363636;\n}\n\ncode {\n  background-color: whitesmoke;\n  color: #da1039;\n  font-size: 0.875em;\n  font-weight: normal;\n  padding: 0.25em 0.5em 0.25em;\n}\n\nhr {\n  background-color: whitesmoke;\n  border: none;\n  display: block;\n  height: 2px;\n  margin: 1.5rem 0;\n}\n\nimg {\n  height: auto;\n  max-width: 100%;\n}\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  vertical-align: baseline;\n}\n\nsmall {\n  font-size: 0.875em;\n}\n\nspan {\n  font-style: inherit;\n  font-weight: inherit;\n}\n\nstrong {\n  color: #363636;\n  font-weight: 700;\n}\n\nfieldset {\n  border: none;\n}\n\npre {\n  -webkit-overflow-scrolling: touch;\n  background-color: whitesmoke;\n  color: #4a4a4a;\n  font-size: 0.875em;\n  overflow-x: auto;\n  padding: 1.25rem 1.5rem;\n  white-space: pre;\n  word-wrap: normal;\n}\n\npre code {\n  background-color: transparent;\n  color: currentColor;\n  font-size: 1em;\n  padding: 0;\n}\n\ntable td,\ntable th {\n  vertical-align: top;\n}\n\ntable td:not([align]),\ntable th:not([align]) {\n  text-align: inherit;\n}\n\ntable th {\n  color: #363636;\n}\n\n@-webkit-keyframes spinAround {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(359deg);\n  }\n}\n\n@keyframes spinAround {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(359deg);\n  }\n}\n\n/* Bulma Elements */\n.box {\n  background-color: white;\n  border-radius: 6px;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  color: #4a4a4a;\n  display: block;\n  padding: 1.25rem;\n}\n\na.box:hover, a.box:focus {\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0 0 1px #485fc7;\n}\n\na.box:active {\n  box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2), 0 0 0 1px #485fc7;\n}\n\n.button {\n  background-color: white;\n  border-color: #dbdbdb;\n  border-width: 1px;\n  color: #363636;\n  cursor: pointer;\n  justify-content: center;\n  padding-bottom: calc(0.5em - 1px);\n  padding-left: 1em;\n  padding-right: 1em;\n  padding-top: calc(0.5em - 1px);\n  text-align: center;\n  white-space: nowrap;\n}\n\n.button strong {\n  color: inherit;\n}\n\n.button .icon, .button .icon.is-small, .button .icon.is-medium, .button .icon.is-large {\n  height: 1.5em;\n  width: 1.5em;\n}\n\n.button .icon:first-child:not(:last-child) {\n  margin-left: calc(-0.5em - 1px);\n  margin-right: 0.25em;\n}\n\n.button .icon:last-child:not(:first-child) {\n  margin-left: 0.25em;\n  margin-right: calc(-0.5em - 1px);\n}\n\n.button .icon:first-child:last-child {\n  margin-left: calc(-0.5em - 1px);\n  margin-right: calc(-0.5em - 1px);\n}\n\n.button:hover, .button.is-hovered {\n  border-color: #b5b5b5;\n  color: #363636;\n}\n\n.button:focus, .button.is-focused {\n  border-color: #485fc7;\n  color: #363636;\n}\n\n.button:focus:not(:active), .button.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.button:active, .button.is-active {\n  border-color: #4a4a4a;\n  color: #363636;\n}\n\n.button.is-text {\n  background-color: transparent;\n  border-color: transparent;\n  color: #4a4a4a;\n  text-decoration: underline;\n}\n\n.button.is-text:hover, .button.is-text.is-hovered, .button.is-text:focus, .button.is-text.is-focused {\n  background-color: whitesmoke;\n  color: #363636;\n}\n\n.button.is-text:active, .button.is-text.is-active {\n  background-color: #e8e8e8;\n  color: #363636;\n}\n\n.button.is-text[disabled],\nfieldset[disabled] .button.is-text {\n  background-color: transparent;\n  border-color: transparent;\n  box-shadow: none;\n}\n\n.button.is-ghost {\n  background: none;\n  border-color: transparent;\n  color: #485fc7;\n  text-decoration: none;\n}\n\n.button.is-ghost:hover, .button.is-ghost.is-hovered {\n  color: #485fc7;\n  text-decoration: underline;\n}\n\n.button.is-white {\n  background-color: white;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white:hover, .button.is-white.is-hovered {\n  background-color: #f9f9f9;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white:focus, .button.is-white.is-focused {\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white:focus:not(:active), .button.is-white.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25);\n}\n\n.button.is-white:active, .button.is-white.is-active {\n  background-color: #f2f2f2;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.button.is-white[disabled],\nfieldset[disabled] .button.is-white {\n  background-color: white;\n  border-color: white;\n  box-shadow: none;\n}\n\n.button.is-white.is-inverted {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.button.is-white.is-inverted:hover, .button.is-white.is-inverted.is-hovered {\n  background-color: black;\n}\n\n.button.is-white.is-inverted[disabled],\nfieldset[disabled] .button.is-white.is-inverted {\n  background-color: #0a0a0a;\n  border-color: transparent;\n  box-shadow: none;\n  color: white;\n}\n\n.button.is-white.is-loading::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-white.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  color: white;\n}\n\n.button.is-white.is-outlined:hover, .button.is-white.is-outlined.is-hovered, .button.is-white.is-outlined:focus, .button.is-white.is-outlined.is-focused {\n  background-color: white;\n  border-color: white;\n  color: #0a0a0a;\n}\n\n.button.is-white.is-outlined.is-loading::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-white.is-outlined.is-loading:hover::after, .button.is-white.is-outlined.is-loading.is-hovered::after, .button.is-white.is-outlined.is-loading:focus::after, .button.is-white.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-white.is-outlined[disabled],\nfieldset[disabled] .button.is-white.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  box-shadow: none;\n  color: white;\n}\n\n.button.is-white.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  color: #0a0a0a;\n}\n\n.button.is-white.is-inverted.is-outlined:hover, .button.is-white.is-inverted.is-outlined.is-hovered, .button.is-white.is-inverted.is-outlined:focus, .button.is-white.is-inverted.is-outlined.is-focused {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.button.is-white.is-inverted.is-outlined.is-loading:hover::after, .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-white.is-inverted.is-outlined.is-loading:focus::after, .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-white.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-white.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  box-shadow: none;\n  color: #0a0a0a;\n}\n\n.button.is-black {\n  background-color: #0a0a0a;\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black:hover, .button.is-black.is-hovered {\n  background-color: #040404;\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black:focus, .button.is-black.is-focused {\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black:focus:not(:active), .button.is-black.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25);\n}\n\n.button.is-black:active, .button.is-black.is-active {\n  background-color: black;\n  border-color: transparent;\n  color: white;\n}\n\n.button.is-black[disabled],\nfieldset[disabled] .button.is-black {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  box-shadow: none;\n}\n\n.button.is-black.is-inverted {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-inverted:hover, .button.is-black.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-black.is-inverted[disabled],\nfieldset[disabled] .button.is-black.is-inverted {\n  background-color: white;\n  border-color: transparent;\n  box-shadow: none;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-loading::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-black.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-outlined:hover, .button.is-black.is-outlined.is-hovered, .button.is-black.is-outlined:focus, .button.is-black.is-outlined.is-focused {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  color: white;\n}\n\n.button.is-black.is-outlined.is-loading::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-black.is-outlined.is-loading:hover::after, .button.is-black.is-outlined.is-loading.is-hovered::after, .button.is-black.is-outlined.is-loading:focus::after, .button.is-black.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent white white !important;\n}\n\n.button.is-black.is-outlined[disabled],\nfieldset[disabled] .button.is-black.is-outlined {\n  background-color: transparent;\n  border-color: #0a0a0a;\n  box-shadow: none;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  color: white;\n}\n\n.button.is-black.is-inverted.is-outlined:hover, .button.is-black.is-inverted.is-outlined.is-hovered, .button.is-black.is-inverted.is-outlined:focus, .button.is-black.is-inverted.is-outlined.is-focused {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.button.is-black.is-inverted.is-outlined.is-loading:hover::after, .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-black.is-inverted.is-outlined.is-loading:focus::after, .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #0a0a0a #0a0a0a !important;\n}\n\n.button.is-black.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-black.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: white;\n  box-shadow: none;\n  color: white;\n}\n\n.button.is-light {\n  background-color: whitesmoke;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light:hover, .button.is-light.is-hovered {\n  background-color: #eeeeee;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light:focus, .button.is-light.is-focused {\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light:focus:not(:active), .button.is-light.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25);\n}\n\n.button.is-light:active, .button.is-light.is-active {\n  background-color: #e8e8e8;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light[disabled],\nfieldset[disabled] .button.is-light {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  box-shadow: none;\n}\n\n.button.is-light.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: whitesmoke;\n}\n\n.button.is-light.is-inverted:hover, .button.is-light.is-inverted.is-hovered {\n  background-color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light.is-inverted[disabled],\nfieldset[disabled] .button.is-light.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: transparent;\n  box-shadow: none;\n  color: whitesmoke;\n}\n\n.button.is-light.is-loading::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-light.is-outlined {\n  background-color: transparent;\n  border-color: whitesmoke;\n  color: whitesmoke;\n}\n\n.button.is-light.is-outlined:hover, .button.is-light.is-outlined.is-hovered, .button.is-light.is-outlined:focus, .button.is-light.is-outlined.is-focused {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light.is-outlined.is-loading::after {\n  border-color: transparent transparent whitesmoke whitesmoke !important;\n}\n\n.button.is-light.is-outlined.is-loading:hover::after, .button.is-light.is-outlined.is-loading.is-hovered::after, .button.is-light.is-outlined.is-loading:focus::after, .button.is-light.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-light.is-outlined[disabled],\nfieldset[disabled] .button.is-light.is-outlined {\n  background-color: transparent;\n  border-color: whitesmoke;\n  box-shadow: none;\n  color: whitesmoke;\n}\n\n.button.is-light.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-light.is-inverted.is-outlined:hover, .button.is-light.is-inverted.is-outlined.is-hovered, .button.is-light.is-inverted.is-outlined:focus, .button.is-light.is-inverted.is-outlined.is-focused {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: whitesmoke;\n}\n\n.button.is-light.is-inverted.is-outlined.is-loading:hover::after, .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-light.is-inverted.is-outlined.is-loading:focus::after, .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent whitesmoke whitesmoke !important;\n}\n\n.button.is-light.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-light.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  box-shadow: none;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-dark {\n  background-color: #363636;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark:hover, .button.is-dark.is-hovered {\n  background-color: #2f2f2f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark:focus, .button.is-dark.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark:focus:not(:active), .button.is-dark.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25);\n}\n\n.button.is-dark:active, .button.is-dark.is-active {\n  background-color: #292929;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-dark[disabled],\nfieldset[disabled] .button.is-dark {\n  background-color: #363636;\n  border-color: #363636;\n  box-shadow: none;\n}\n\n.button.is-dark.is-inverted {\n  background-color: #fff;\n  color: #363636;\n}\n\n.button.is-dark.is-inverted:hover, .button.is-dark.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-dark.is-inverted[disabled],\nfieldset[disabled] .button.is-dark.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #363636;\n}\n\n.button.is-dark.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-dark.is-outlined {\n  background-color: transparent;\n  border-color: #363636;\n  color: #363636;\n}\n\n.button.is-dark.is-outlined:hover, .button.is-dark.is-outlined.is-hovered, .button.is-dark.is-outlined:focus, .button.is-dark.is-outlined.is-focused {\n  background-color: #363636;\n  border-color: #363636;\n  color: #fff;\n}\n\n.button.is-dark.is-outlined.is-loading::after {\n  border-color: transparent transparent #363636 #363636 !important;\n}\n\n.button.is-dark.is-outlined.is-loading:hover::after, .button.is-dark.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-outlined.is-loading:focus::after, .button.is-dark.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-dark.is-outlined[disabled],\nfieldset[disabled] .button.is-dark.is-outlined {\n  background-color: transparent;\n  border-color: #363636;\n  box-shadow: none;\n  color: #363636;\n}\n\n.button.is-dark.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-dark.is-inverted.is-outlined:hover, .button.is-dark.is-inverted.is-outlined.is-hovered, .button.is-dark.is-inverted.is-outlined:focus, .button.is-dark.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #363636;\n}\n\n.button.is-dark.is-inverted.is-outlined.is-loading:hover::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-inverted.is-outlined.is-loading:focus::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #363636 #363636 !important;\n}\n\n.button.is-dark.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-dark.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-primary {\n  background-color: #00d1b2;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary:hover, .button.is-primary.is-hovered {\n  background-color: #00c4a7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary:focus, .button.is-primary.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary:focus:not(:active), .button.is-primary.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25);\n}\n\n.button.is-primary:active, .button.is-primary.is-active {\n  background-color: #00b89c;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-primary[disabled],\nfieldset[disabled] .button.is-primary {\n  background-color: #00d1b2;\n  border-color: #00d1b2;\n  box-shadow: none;\n}\n\n.button.is-primary.is-inverted {\n  background-color: #fff;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-inverted:hover, .button.is-primary.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-primary.is-inverted[disabled],\nfieldset[disabled] .button.is-primary.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-primary.is-outlined {\n  background-color: transparent;\n  border-color: #00d1b2;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-outlined:hover, .button.is-primary.is-outlined.is-hovered, .button.is-primary.is-outlined:focus, .button.is-primary.is-outlined.is-focused {\n  background-color: #00d1b2;\n  border-color: #00d1b2;\n  color: #fff;\n}\n\n.button.is-primary.is-outlined.is-loading::after {\n  border-color: transparent transparent #00d1b2 #00d1b2 !important;\n}\n\n.button.is-primary.is-outlined.is-loading:hover::after, .button.is-primary.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-outlined.is-loading:focus::after, .button.is-primary.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-primary.is-outlined[disabled],\nfieldset[disabled] .button.is-primary.is-outlined {\n  background-color: transparent;\n  border-color: #00d1b2;\n  box-shadow: none;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-primary.is-inverted.is-outlined:hover, .button.is-primary.is-inverted.is-outlined.is-hovered, .button.is-primary.is-inverted.is-outlined:focus, .button.is-primary.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #00d1b2;\n}\n\n.button.is-primary.is-inverted.is-outlined.is-loading:hover::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-inverted.is-outlined.is-loading:focus::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #00d1b2 #00d1b2 !important;\n}\n\n.button.is-primary.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-primary.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-primary.is-light {\n  background-color: #ebfffc;\n  color: #00947e;\n}\n\n.button.is-primary.is-light:hover, .button.is-primary.is-light.is-hovered {\n  background-color: #defffa;\n  border-color: transparent;\n  color: #00947e;\n}\n\n.button.is-primary.is-light:active, .button.is-primary.is-light.is-active {\n  background-color: #d1fff8;\n  border-color: transparent;\n  color: #00947e;\n}\n\n.button.is-link {\n  background-color: #485fc7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link:hover, .button.is-link.is-hovered {\n  background-color: #3e56c4;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link:focus, .button.is-link.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link:focus:not(:active), .button.is-link.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.button.is-link:active, .button.is-link.is-active {\n  background-color: #3a51bb;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-link[disabled],\nfieldset[disabled] .button.is-link {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  box-shadow: none;\n}\n\n.button.is-link.is-inverted {\n  background-color: #fff;\n  color: #485fc7;\n}\n\n.button.is-link.is-inverted:hover, .button.is-link.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-link.is-inverted[disabled],\nfieldset[disabled] .button.is-link.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #485fc7;\n}\n\n.button.is-link.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-link.is-outlined {\n  background-color: transparent;\n  border-color: #485fc7;\n  color: #485fc7;\n}\n\n.button.is-link.is-outlined:hover, .button.is-link.is-outlined.is-hovered, .button.is-link.is-outlined:focus, .button.is-link.is-outlined.is-focused {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n}\n\n.button.is-link.is-outlined.is-loading::after {\n  border-color: transparent transparent #485fc7 #485fc7 !important;\n}\n\n.button.is-link.is-outlined.is-loading:hover::after, .button.is-link.is-outlined.is-loading.is-hovered::after, .button.is-link.is-outlined.is-loading:focus::after, .button.is-link.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-link.is-outlined[disabled],\nfieldset[disabled] .button.is-link.is-outlined {\n  background-color: transparent;\n  border-color: #485fc7;\n  box-shadow: none;\n  color: #485fc7;\n}\n\n.button.is-link.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-link.is-inverted.is-outlined:hover, .button.is-link.is-inverted.is-outlined.is-hovered, .button.is-link.is-inverted.is-outlined:focus, .button.is-link.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #485fc7;\n}\n\n.button.is-link.is-inverted.is-outlined.is-loading:hover::after, .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-link.is-inverted.is-outlined.is-loading:focus::after, .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #485fc7 #485fc7 !important;\n}\n\n.button.is-link.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-link.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-link.is-light {\n  background-color: #eff1fa;\n  color: #3850b7;\n}\n\n.button.is-link.is-light:hover, .button.is-link.is-light.is-hovered {\n  background-color: #e6e9f7;\n  border-color: transparent;\n  color: #3850b7;\n}\n\n.button.is-link.is-light:active, .button.is-link.is-light.is-active {\n  background-color: #dce0f4;\n  border-color: transparent;\n  color: #3850b7;\n}\n\n.button.is-info {\n  background-color: #3e8ed0;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info:hover, .button.is-info.is-hovered {\n  background-color: #3488ce;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info:focus, .button.is-info.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info:focus:not(:active), .button.is-info.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(62, 142, 208, 0.25);\n}\n\n.button.is-info:active, .button.is-info.is-active {\n  background-color: #3082c5;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-info[disabled],\nfieldset[disabled] .button.is-info {\n  background-color: #3e8ed0;\n  border-color: #3e8ed0;\n  box-shadow: none;\n}\n\n.button.is-info.is-inverted {\n  background-color: #fff;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-inverted:hover, .button.is-info.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-info.is-inverted[disabled],\nfieldset[disabled] .button.is-info.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-info.is-outlined {\n  background-color: transparent;\n  border-color: #3e8ed0;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-outlined:hover, .button.is-info.is-outlined.is-hovered, .button.is-info.is-outlined:focus, .button.is-info.is-outlined.is-focused {\n  background-color: #3e8ed0;\n  border-color: #3e8ed0;\n  color: #fff;\n}\n\n.button.is-info.is-outlined.is-loading::after {\n  border-color: transparent transparent #3e8ed0 #3e8ed0 !important;\n}\n\n.button.is-info.is-outlined.is-loading:hover::after, .button.is-info.is-outlined.is-loading.is-hovered::after, .button.is-info.is-outlined.is-loading:focus::after, .button.is-info.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-info.is-outlined[disabled],\nfieldset[disabled] .button.is-info.is-outlined {\n  background-color: transparent;\n  border-color: #3e8ed0;\n  box-shadow: none;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-info.is-inverted.is-outlined:hover, .button.is-info.is-inverted.is-outlined.is-hovered, .button.is-info.is-inverted.is-outlined:focus, .button.is-info.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #3e8ed0;\n}\n\n.button.is-info.is-inverted.is-outlined.is-loading:hover::after, .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-info.is-inverted.is-outlined.is-loading:focus::after, .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #3e8ed0 #3e8ed0 !important;\n}\n\n.button.is-info.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-info.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-info.is-light {\n  background-color: #eff5fb;\n  color: #296fa8;\n}\n\n.button.is-info.is-light:hover, .button.is-info.is-light.is-hovered {\n  background-color: #e4eff9;\n  border-color: transparent;\n  color: #296fa8;\n}\n\n.button.is-info.is-light:active, .button.is-info.is-light.is-active {\n  background-color: #dae9f6;\n  border-color: transparent;\n  color: #296fa8;\n}\n\n.button.is-success {\n  background-color: #48c78e;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success:hover, .button.is-success.is-hovered {\n  background-color: #3ec487;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success:focus, .button.is-success.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success:focus:not(:active), .button.is-success.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(72, 199, 142, 0.25);\n}\n\n.button.is-success:active, .button.is-success.is-active {\n  background-color: #3abb81;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-success[disabled],\nfieldset[disabled] .button.is-success {\n  background-color: #48c78e;\n  border-color: #48c78e;\n  box-shadow: none;\n}\n\n.button.is-success.is-inverted {\n  background-color: #fff;\n  color: #48c78e;\n}\n\n.button.is-success.is-inverted:hover, .button.is-success.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-success.is-inverted[disabled],\nfieldset[disabled] .button.is-success.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #48c78e;\n}\n\n.button.is-success.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-success.is-outlined {\n  background-color: transparent;\n  border-color: #48c78e;\n  color: #48c78e;\n}\n\n.button.is-success.is-outlined:hover, .button.is-success.is-outlined.is-hovered, .button.is-success.is-outlined:focus, .button.is-success.is-outlined.is-focused {\n  background-color: #48c78e;\n  border-color: #48c78e;\n  color: #fff;\n}\n\n.button.is-success.is-outlined.is-loading::after {\n  border-color: transparent transparent #48c78e #48c78e !important;\n}\n\n.button.is-success.is-outlined.is-loading:hover::after, .button.is-success.is-outlined.is-loading.is-hovered::after, .button.is-success.is-outlined.is-loading:focus::after, .button.is-success.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-success.is-outlined[disabled],\nfieldset[disabled] .button.is-success.is-outlined {\n  background-color: transparent;\n  border-color: #48c78e;\n  box-shadow: none;\n  color: #48c78e;\n}\n\n.button.is-success.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-success.is-inverted.is-outlined:hover, .button.is-success.is-inverted.is-outlined.is-hovered, .button.is-success.is-inverted.is-outlined:focus, .button.is-success.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #48c78e;\n}\n\n.button.is-success.is-inverted.is-outlined.is-loading:hover::after, .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-success.is-inverted.is-outlined.is-loading:focus::after, .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #48c78e #48c78e !important;\n}\n\n.button.is-success.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-success.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-success.is-light {\n  background-color: #effaf5;\n  color: #257953;\n}\n\n.button.is-success.is-light:hover, .button.is-success.is-light.is-hovered {\n  background-color: #e6f7ef;\n  border-color: transparent;\n  color: #257953;\n}\n\n.button.is-success.is-light:active, .button.is-success.is-light.is-active {\n  background-color: #dcf4e9;\n  border-color: transparent;\n  color: #257953;\n}\n\n.button.is-warning {\n  background-color: #ffe08a;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning:hover, .button.is-warning.is-hovered {\n  background-color: #ffdc7d;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning:focus, .button.is-warning.is-focused {\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning:focus:not(:active), .button.is-warning.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(255, 224, 138, 0.25);\n}\n\n.button.is-warning:active, .button.is-warning.is-active {\n  background-color: #ffd970;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning[disabled],\nfieldset[disabled] .button.is-warning {\n  background-color: #ffe08a;\n  border-color: #ffe08a;\n  box-shadow: none;\n}\n\n.button.is-warning.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: #ffe08a;\n}\n\n.button.is-warning.is-inverted:hover, .button.is-warning.is-inverted.is-hovered {\n  background-color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-inverted[disabled],\nfieldset[disabled] .button.is-warning.is-inverted {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: transparent;\n  box-shadow: none;\n  color: #ffe08a;\n}\n\n.button.is-warning.is-loading::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-warning.is-outlined {\n  background-color: transparent;\n  border-color: #ffe08a;\n  color: #ffe08a;\n}\n\n.button.is-warning.is-outlined:hover, .button.is-warning.is-outlined.is-hovered, .button.is-warning.is-outlined:focus, .button.is-warning.is-outlined.is-focused {\n  background-color: #ffe08a;\n  border-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-outlined.is-loading::after {\n  border-color: transparent transparent #ffe08a #ffe08a !important;\n}\n\n.button.is-warning.is-outlined.is-loading:hover::after, .button.is-warning.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-outlined.is-loading:focus::after, .button.is-warning.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important;\n}\n\n.button.is-warning.is-outlined[disabled],\nfieldset[disabled] .button.is-warning.is-outlined {\n  background-color: transparent;\n  border-color: #ffe08a;\n  box-shadow: none;\n  color: #ffe08a;\n}\n\n.button.is-warning.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-inverted.is-outlined:hover, .button.is-warning.is-inverted.is-outlined.is-hovered, .button.is-warning.is-inverted.is-outlined:focus, .button.is-warning.is-inverted.is-outlined.is-focused {\n  background-color: rgba(0, 0, 0, 0.7);\n  color: #ffe08a;\n}\n\n.button.is-warning.is-inverted.is-outlined.is-loading:hover::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-inverted.is-outlined.is-loading:focus::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #ffe08a #ffe08a !important;\n}\n\n.button.is-warning.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-warning.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: rgba(0, 0, 0, 0.7);\n  box-shadow: none;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.button.is-warning.is-light {\n  background-color: #fffaeb;\n  color: #946c00;\n}\n\n.button.is-warning.is-light:hover, .button.is-warning.is-light.is-hovered {\n  background-color: #fff6de;\n  border-color: transparent;\n  color: #946c00;\n}\n\n.button.is-warning.is-light:active, .button.is-warning.is-light.is-active {\n  background-color: #fff3d1;\n  border-color: transparent;\n  color: #946c00;\n}\n\n.button.is-danger {\n  background-color: #f14668;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger:hover, .button.is-danger.is-hovered {\n  background-color: #f03a5f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger:focus, .button.is-danger.is-focused {\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger:focus:not(:active), .button.is-danger.is-focused:not(:active) {\n  box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25);\n}\n\n.button.is-danger:active, .button.is-danger.is-active {\n  background-color: #ef2e55;\n  border-color: transparent;\n  color: #fff;\n}\n\n.button.is-danger[disabled],\nfieldset[disabled] .button.is-danger {\n  background-color: #f14668;\n  border-color: #f14668;\n  box-shadow: none;\n}\n\n.button.is-danger.is-inverted {\n  background-color: #fff;\n  color: #f14668;\n}\n\n.button.is-danger.is-inverted:hover, .button.is-danger.is-inverted.is-hovered {\n  background-color: #f2f2f2;\n}\n\n.button.is-danger.is-inverted[disabled],\nfieldset[disabled] .button.is-danger.is-inverted {\n  background-color: #fff;\n  border-color: transparent;\n  box-shadow: none;\n  color: #f14668;\n}\n\n.button.is-danger.is-loading::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-danger.is-outlined {\n  background-color: transparent;\n  border-color: #f14668;\n  color: #f14668;\n}\n\n.button.is-danger.is-outlined:hover, .button.is-danger.is-outlined.is-hovered, .button.is-danger.is-outlined:focus, .button.is-danger.is-outlined.is-focused {\n  background-color: #f14668;\n  border-color: #f14668;\n  color: #fff;\n}\n\n.button.is-danger.is-outlined.is-loading::after {\n  border-color: transparent transparent #f14668 #f14668 !important;\n}\n\n.button.is-danger.is-outlined.is-loading:hover::after, .button.is-danger.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-outlined.is-loading:focus::after, .button.is-danger.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #fff #fff !important;\n}\n\n.button.is-danger.is-outlined[disabled],\nfieldset[disabled] .button.is-danger.is-outlined {\n  background-color: transparent;\n  border-color: #f14668;\n  box-shadow: none;\n  color: #f14668;\n}\n\n.button.is-danger.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  color: #fff;\n}\n\n.button.is-danger.is-inverted.is-outlined:hover, .button.is-danger.is-inverted.is-outlined.is-hovered, .button.is-danger.is-inverted.is-outlined:focus, .button.is-danger.is-inverted.is-outlined.is-focused {\n  background-color: #fff;\n  color: #f14668;\n}\n\n.button.is-danger.is-inverted.is-outlined.is-loading:hover::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-inverted.is-outlined.is-loading:focus::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after {\n  border-color: transparent transparent #f14668 #f14668 !important;\n}\n\n.button.is-danger.is-inverted.is-outlined[disabled],\nfieldset[disabled] .button.is-danger.is-inverted.is-outlined {\n  background-color: transparent;\n  border-color: #fff;\n  box-shadow: none;\n  color: #fff;\n}\n\n.button.is-danger.is-light {\n  background-color: #feecf0;\n  color: #cc0f35;\n}\n\n.button.is-danger.is-light:hover, .button.is-danger.is-light.is-hovered {\n  background-color: #fde0e6;\n  border-color: transparent;\n  color: #cc0f35;\n}\n\n.button.is-danger.is-light:active, .button.is-danger.is-light.is-active {\n  background-color: #fcd4dc;\n  border-color: transparent;\n  color: #cc0f35;\n}\n\n.button.is-small {\n  font-size: 0.75rem;\n}\n\n.button.is-small:not(.is-rounded) {\n  border-radius: 2px;\n}\n\n.button.is-normal {\n  font-size: 1rem;\n}\n\n.button.is-medium {\n  font-size: 1.25rem;\n}\n\n.button.is-large {\n  font-size: 1.5rem;\n}\n\n.button[disabled],\nfieldset[disabled] .button {\n  background-color: white;\n  border-color: #dbdbdb;\n  box-shadow: none;\n  opacity: 0.5;\n}\n\n.button.is-fullwidth {\n  display: flex;\n  width: 100%;\n}\n\n.button.is-loading {\n  color: transparent !important;\n  pointer-events: none;\n}\n\n.button.is-loading::after {\n  position: absolute;\n  left: calc(50% - (1em * 0.5));\n  top: calc(50% - (1em * 0.5));\n  position: absolute !important;\n}\n\n.button.is-static {\n  background-color: whitesmoke;\n  border-color: #dbdbdb;\n  color: #7a7a7a;\n  box-shadow: none;\n  pointer-events: none;\n}\n\n.button.is-rounded {\n  border-radius: 9999px;\n  padding-left: calc(1em + 0.25em);\n  padding-right: calc(1em + 0.25em);\n}\n\n.buttons {\n  align-items: center;\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n\n.buttons .button {\n  margin-bottom: 0.5rem;\n}\n\n.buttons .button:not(:last-child):not(.is-fullwidth) {\n  margin-right: 0.5rem;\n}\n\n.buttons:last-child {\n  margin-bottom: -0.5rem;\n}\n\n.buttons:not(:last-child) {\n  margin-bottom: 1rem;\n}\n\n.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large) {\n  font-size: 0.75rem;\n}\n\n.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded) {\n  border-radius: 2px;\n}\n\n.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large) {\n  font-size: 1.25rem;\n}\n\n.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium) {\n  font-size: 1.5rem;\n}\n\n.buttons.has-addons .button:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.buttons.has-addons .button:not(:last-child) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n  margin-right: -1px;\n}\n\n.buttons.has-addons .button:last-child {\n  margin-right: 0;\n}\n\n.buttons.has-addons .button:hover, .buttons.has-addons .button.is-hovered {\n  z-index: 2;\n}\n\n.buttons.has-addons .button:focus, .buttons.has-addons .button.is-focused, .buttons.has-addons .button:active, .buttons.has-addons .button.is-active, .buttons.has-addons .button.is-selected {\n  z-index: 3;\n}\n\n.buttons.has-addons .button:focus:hover, .buttons.has-addons .button.is-focused:hover, .buttons.has-addons .button:active:hover, .buttons.has-addons .button.is-active:hover, .buttons.has-addons .button.is-selected:hover {\n  z-index: 4;\n}\n\n.buttons.has-addons .button.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.buttons.is-centered {\n  justify-content: center;\n}\n\n.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth) {\n  margin-left: 0.25rem;\n  margin-right: 0.25rem;\n}\n\n.buttons.is-right {\n  justify-content: flex-end;\n}\n\n.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth) {\n  margin-left: 0.25rem;\n  margin-right: 0.25rem;\n}\n\n@media screen and (max-width: 768px) {\n  .button.is-responsive.is-small {\n    font-size: 0.5625rem;\n  }\n  .button.is-responsive,\n  .button.is-responsive.is-normal {\n    font-size: 0.65625rem;\n  }\n  .button.is-responsive.is-medium {\n    font-size: 0.75rem;\n  }\n  .button.is-responsive.is-large {\n    font-size: 1rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .button.is-responsive.is-small {\n    font-size: 0.65625rem;\n  }\n  .button.is-responsive,\n  .button.is-responsive.is-normal {\n    font-size: 0.75rem;\n  }\n  .button.is-responsive.is-medium {\n    font-size: 1rem;\n  }\n  .button.is-responsive.is-large {\n    font-size: 1.25rem;\n  }\n}\n\n.container {\n  flex-grow: 1;\n  margin: 0 auto;\n  position: relative;\n  width: auto;\n}\n\n.container.is-fluid {\n  max-width: none !important;\n  padding-left: 32px;\n  padding-right: 32px;\n  width: 100%;\n}\n\n@media screen and (min-width: 1024px) {\n  .container {\n    max-width: 960px;\n  }\n}\n\n@media screen and (max-width: 1215px) {\n  .container.is-widescreen:not(.is-max-desktop) {\n    max-width: 1152px;\n  }\n}\n\n@media screen and (max-width: 1407px) {\n  .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen) {\n    max-width: 1344px;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .container:not(.is-max-desktop) {\n    max-width: 1152px;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .container:not(.is-max-desktop):not(.is-max-widescreen) {\n    max-width: 1344px;\n  }\n}\n\n.content li + li {\n  margin-top: 0.25em;\n}\n\n.content p:not(:last-child),\n.content dl:not(:last-child),\n.content ol:not(:last-child),\n.content ul:not(:last-child),\n.content blockquote:not(:last-child),\n.content pre:not(:last-child),\n.content table:not(:last-child) {\n  margin-bottom: 1em;\n}\n\n.content h1,\n.content h2,\n.content h3,\n.content h4,\n.content h5,\n.content h6 {\n  color: #363636;\n  font-weight: 600;\n  line-height: 1.125;\n}\n\n.content h1 {\n  font-size: 2em;\n  margin-bottom: 0.5em;\n}\n\n.content h1:not(:first-child) {\n  margin-top: 1em;\n}\n\n.content h2 {\n  font-size: 1.75em;\n  margin-bottom: 0.5714em;\n}\n\n.content h2:not(:first-child) {\n  margin-top: 1.1428em;\n}\n\n.content h3 {\n  font-size: 1.5em;\n  margin-bottom: 0.6666em;\n}\n\n.content h3:not(:first-child) {\n  margin-top: 1.3333em;\n}\n\n.content h4 {\n  font-size: 1.25em;\n  margin-bottom: 0.8em;\n}\n\n.content h5 {\n  font-size: 1.125em;\n  margin-bottom: 0.8888em;\n}\n\n.content h6 {\n  font-size: 1em;\n  margin-bottom: 1em;\n}\n\n.content blockquote {\n  background-color: whitesmoke;\n  border-left: 5px solid #dbdbdb;\n  padding: 1.25em 1.5em;\n}\n\n.content ol {\n  list-style-position: outside;\n  margin-left: 2em;\n  margin-top: 1em;\n}\n\n.content ol:not([type]) {\n  list-style-type: decimal;\n}\n\n.content ol:not([type]).is-lower-alpha {\n  list-style-type: lower-alpha;\n}\n\n.content ol:not([type]).is-lower-roman {\n  list-style-type: lower-roman;\n}\n\n.content ol:not([type]).is-upper-alpha {\n  list-style-type: upper-alpha;\n}\n\n.content ol:not([type]).is-upper-roman {\n  list-style-type: upper-roman;\n}\n\n.content ul {\n  list-style: disc outside;\n  margin-left: 2em;\n  margin-top: 1em;\n}\n\n.content ul ul {\n  list-style-type: circle;\n  margin-top: 0.5em;\n}\n\n.content ul ul ul {\n  list-style-type: square;\n}\n\n.content dd {\n  margin-left: 2em;\n}\n\n.content figure {\n  margin-left: 2em;\n  margin-right: 2em;\n  text-align: center;\n}\n\n.content figure:not(:first-child) {\n  margin-top: 2em;\n}\n\n.content figure:not(:last-child) {\n  margin-bottom: 2em;\n}\n\n.content figure img {\n  display: inline-block;\n}\n\n.content figure figcaption {\n  font-style: italic;\n}\n\n.content pre {\n  -webkit-overflow-scrolling: touch;\n  overflow-x: auto;\n  padding: 1.25em 1.5em;\n  white-space: pre;\n  word-wrap: normal;\n}\n\n.content sup,\n.content sub {\n  font-size: 75%;\n}\n\n.content table {\n  width: 100%;\n}\n\n.content table td,\n.content table th {\n  border: 1px solid #dbdbdb;\n  border-width: 0 0 1px;\n  padding: 0.5em 0.75em;\n  vertical-align: top;\n}\n\n.content table th {\n  color: #363636;\n}\n\n.content table th:not([align]) {\n  text-align: inherit;\n}\n\n.content table thead td,\n.content table thead th {\n  border-width: 0 0 2px;\n  color: #363636;\n}\n\n.content table tfoot td,\n.content table tfoot th {\n  border-width: 2px 0 0;\n  color: #363636;\n}\n\n.content table tbody tr:last-child td,\n.content table tbody tr:last-child th {\n  border-bottom-width: 0;\n}\n\n.content .tabs li + li {\n  margin-top: 0;\n}\n\n.content.is-small {\n  font-size: 0.75rem;\n}\n\n.content.is-normal {\n  font-size: 1rem;\n}\n\n.content.is-medium {\n  font-size: 1.25rem;\n}\n\n.content.is-large {\n  font-size: 1.5rem;\n}\n\n.icon {\n  align-items: center;\n  display: inline-flex;\n  justify-content: center;\n  height: 1.5rem;\n  width: 1.5rem;\n}\n\n.icon.is-small {\n  height: 1rem;\n  width: 1rem;\n}\n\n.icon.is-medium {\n  height: 2rem;\n  width: 2rem;\n}\n\n.icon.is-large {\n  height: 3rem;\n  width: 3rem;\n}\n\n.icon-text {\n  align-items: flex-start;\n  color: inherit;\n  display: inline-flex;\n  flex-wrap: wrap;\n  line-height: 1.5rem;\n  vertical-align: top;\n}\n\n.icon-text .icon {\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.icon-text .icon:not(:last-child) {\n  margin-right: 0.25em;\n}\n\n.icon-text .icon:not(:first-child) {\n  margin-left: 0.25em;\n}\n\ndiv.icon-text {\n  display: flex;\n}\n\n.image {\n  display: block;\n  position: relative;\n}\n\n.image img {\n  display: block;\n  height: auto;\n  width: 100%;\n}\n\n.image img.is-rounded {\n  border-radius: 9999px;\n}\n\n.image.is-fullwidth {\n  width: 100%;\n}\n\n.image.is-square img,\n.image.is-square .has-ratio, .image.is-1by1 img,\n.image.is-1by1 .has-ratio, .image.is-5by4 img,\n.image.is-5by4 .has-ratio, .image.is-4by3 img,\n.image.is-4by3 .has-ratio, .image.is-3by2 img,\n.image.is-3by2 .has-ratio, .image.is-5by3 img,\n.image.is-5by3 .has-ratio, .image.is-16by9 img,\n.image.is-16by9 .has-ratio, .image.is-2by1 img,\n.image.is-2by1 .has-ratio, .image.is-3by1 img,\n.image.is-3by1 .has-ratio, .image.is-4by5 img,\n.image.is-4by5 .has-ratio, .image.is-3by4 img,\n.image.is-3by4 .has-ratio, .image.is-2by3 img,\n.image.is-2by3 .has-ratio, .image.is-3by5 img,\n.image.is-3by5 .has-ratio, .image.is-9by16 img,\n.image.is-9by16 .has-ratio, .image.is-1by2 img,\n.image.is-1by2 .has-ratio, .image.is-1by3 img,\n.image.is-1by3 .has-ratio {\n  height: 100%;\n  width: 100%;\n}\n\n.image.is-square, .image.is-1by1 {\n  padding-top: 100%;\n}\n\n.image.is-5by4 {\n  padding-top: 80%;\n}\n\n.image.is-4by3 {\n  padding-top: 75%;\n}\n\n.image.is-3by2 {\n  padding-top: 66.6666%;\n}\n\n.image.is-5by3 {\n  padding-top: 60%;\n}\n\n.image.is-16by9 {\n  padding-top: 56.25%;\n}\n\n.image.is-2by1 {\n  padding-top: 50%;\n}\n\n.image.is-3by1 {\n  padding-top: 33.3333%;\n}\n\n.image.is-4by5 {\n  padding-top: 125%;\n}\n\n.image.is-3by4 {\n  padding-top: 133.3333%;\n}\n\n.image.is-2by3 {\n  padding-top: 150%;\n}\n\n.image.is-3by5 {\n  padding-top: 166.6666%;\n}\n\n.image.is-9by16 {\n  padding-top: 177.7777%;\n}\n\n.image.is-1by2 {\n  padding-top: 200%;\n}\n\n.image.is-1by3 {\n  padding-top: 300%;\n}\n\n.image.is-16x16 {\n  height: 16px;\n  width: 16px;\n}\n\n.image.is-24x24 {\n  height: 24px;\n  width: 24px;\n}\n\n.image.is-32x32 {\n  height: 32px;\n  width: 32px;\n}\n\n.image.is-48x48 {\n  height: 48px;\n  width: 48px;\n}\n\n.image.is-64x64 {\n  height: 64px;\n  width: 64px;\n}\n\n.image.is-96x96 {\n  height: 96px;\n  width: 96px;\n}\n\n.image.is-128x128 {\n  height: 128px;\n  width: 128px;\n}\n\n.notification {\n  background-color: whitesmoke;\n  border-radius: 4px;\n  position: relative;\n  padding: 1.25rem 2.5rem 1.25rem 1.5rem;\n}\n\n.notification a:not(.button):not(.dropdown-item) {\n  color: currentColor;\n  text-decoration: underline;\n}\n\n.notification strong {\n  color: currentColor;\n}\n\n.notification code,\n.notification pre {\n  background: white;\n}\n\n.notification pre code {\n  background: transparent;\n}\n\n.notification > .delete {\n  right: 0.5rem;\n  position: absolute;\n  top: 0.5rem;\n}\n\n.notification .title,\n.notification .subtitle,\n.notification .content {\n  color: currentColor;\n}\n\n.notification.is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.notification.is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.notification.is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.notification.is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.notification.is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.notification.is-primary.is-light {\n  background-color: #ebfffc;\n  color: #00947e;\n}\n\n.notification.is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.notification.is-link.is-light {\n  background-color: #eff1fa;\n  color: #3850b7;\n}\n\n.notification.is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.notification.is-info.is-light {\n  background-color: #eff5fb;\n  color: #296fa8;\n}\n\n.notification.is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.notification.is-success.is-light {\n  background-color: #effaf5;\n  color: #257953;\n}\n\n.notification.is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.notification.is-warning.is-light {\n  background-color: #fffaeb;\n  color: #946c00;\n}\n\n.notification.is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.notification.is-danger.is-light {\n  background-color: #feecf0;\n  color: #cc0f35;\n}\n\n.progress {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  border: none;\n  border-radius: 9999px;\n  display: block;\n  height: 1rem;\n  overflow: hidden;\n  padding: 0;\n  width: 100%;\n}\n\n.progress::-webkit-progress-bar {\n  background-color: #ededed;\n}\n\n.progress::-webkit-progress-value {\n  background-color: #4a4a4a;\n}\n\n.progress::-moz-progress-bar {\n  background-color: #4a4a4a;\n}\n\n.progress::-ms-fill {\n  background-color: #4a4a4a;\n  border: none;\n}\n\n.progress.is-white::-webkit-progress-value {\n  background-color: white;\n}\n\n.progress.is-white::-moz-progress-bar {\n  background-color: white;\n}\n\n.progress.is-white::-ms-fill {\n  background-color: white;\n}\n\n.progress.is-white:indeterminate {\n  background-image: linear-gradient(to right, white 30%, #ededed 30%);\n}\n\n.progress.is-black::-webkit-progress-value {\n  background-color: #0a0a0a;\n}\n\n.progress.is-black::-moz-progress-bar {\n  background-color: #0a0a0a;\n}\n\n.progress.is-black::-ms-fill {\n  background-color: #0a0a0a;\n}\n\n.progress.is-black:indeterminate {\n  background-image: linear-gradient(to right, #0a0a0a 30%, #ededed 30%);\n}\n\n.progress.is-light::-webkit-progress-value {\n  background-color: whitesmoke;\n}\n\n.progress.is-light::-moz-progress-bar {\n  background-color: whitesmoke;\n}\n\n.progress.is-light::-ms-fill {\n  background-color: whitesmoke;\n}\n\n.progress.is-light:indeterminate {\n  background-image: linear-gradient(to right, whitesmoke 30%, #ededed 30%);\n}\n\n.progress.is-dark::-webkit-progress-value {\n  background-color: #363636;\n}\n\n.progress.is-dark::-moz-progress-bar {\n  background-color: #363636;\n}\n\n.progress.is-dark::-ms-fill {\n  background-color: #363636;\n}\n\n.progress.is-dark:indeterminate {\n  background-image: linear-gradient(to right, #363636 30%, #ededed 30%);\n}\n\n.progress.is-primary::-webkit-progress-value {\n  background-color: #00d1b2;\n}\n\n.progress.is-primary::-moz-progress-bar {\n  background-color: #00d1b2;\n}\n\n.progress.is-primary::-ms-fill {\n  background-color: #00d1b2;\n}\n\n.progress.is-primary:indeterminate {\n  background-image: linear-gradient(to right, #00d1b2 30%, #ededed 30%);\n}\n\n.progress.is-link::-webkit-progress-value {\n  background-color: #485fc7;\n}\n\n.progress.is-link::-moz-progress-bar {\n  background-color: #485fc7;\n}\n\n.progress.is-link::-ms-fill {\n  background-color: #485fc7;\n}\n\n.progress.is-link:indeterminate {\n  background-image: linear-gradient(to right, #485fc7 30%, #ededed 30%);\n}\n\n.progress.is-info::-webkit-progress-value {\n  background-color: #3e8ed0;\n}\n\n.progress.is-info::-moz-progress-bar {\n  background-color: #3e8ed0;\n}\n\n.progress.is-info::-ms-fill {\n  background-color: #3e8ed0;\n}\n\n.progress.is-info:indeterminate {\n  background-image: linear-gradient(to right, #3e8ed0 30%, #ededed 30%);\n}\n\n.progress.is-success::-webkit-progress-value {\n  background-color: #48c78e;\n}\n\n.progress.is-success::-moz-progress-bar {\n  background-color: #48c78e;\n}\n\n.progress.is-success::-ms-fill {\n  background-color: #48c78e;\n}\n\n.progress.is-success:indeterminate {\n  background-image: linear-gradient(to right, #48c78e 30%, #ededed 30%);\n}\n\n.progress.is-warning::-webkit-progress-value {\n  background-color: #ffe08a;\n}\n\n.progress.is-warning::-moz-progress-bar {\n  background-color: #ffe08a;\n}\n\n.progress.is-warning::-ms-fill {\n  background-color: #ffe08a;\n}\n\n.progress.is-warning:indeterminate {\n  background-image: linear-gradient(to right, #ffe08a 30%, #ededed 30%);\n}\n\n.progress.is-danger::-webkit-progress-value {\n  background-color: #f14668;\n}\n\n.progress.is-danger::-moz-progress-bar {\n  background-color: #f14668;\n}\n\n.progress.is-danger::-ms-fill {\n  background-color: #f14668;\n}\n\n.progress.is-danger:indeterminate {\n  background-image: linear-gradient(to right, #f14668 30%, #ededed 30%);\n}\n\n.progress:indeterminate {\n  -webkit-animation-duration: 1.5s;\n          animation-duration: 1.5s;\n  -webkit-animation-iteration-count: infinite;\n          animation-iteration-count: infinite;\n  -webkit-animation-name: moveIndeterminate;\n          animation-name: moveIndeterminate;\n  -webkit-animation-timing-function: linear;\n          animation-timing-function: linear;\n  background-color: #ededed;\n  background-image: linear-gradient(to right, #4a4a4a 30%, #ededed 30%);\n  background-position: top left;\n  background-repeat: no-repeat;\n  background-size: 150% 150%;\n}\n\n.progress:indeterminate::-webkit-progress-bar {\n  background-color: transparent;\n}\n\n.progress:indeterminate::-moz-progress-bar {\n  background-color: transparent;\n}\n\n.progress:indeterminate::-ms-fill {\n  animation-name: none;\n}\n\n.progress.is-small {\n  height: 0.75rem;\n}\n\n.progress.is-medium {\n  height: 1.25rem;\n}\n\n.progress.is-large {\n  height: 1.5rem;\n}\n\n@-webkit-keyframes moveIndeterminate {\n  from {\n    background-position: 200% 0;\n  }\n  to {\n    background-position: -200% 0;\n  }\n}\n\n@keyframes moveIndeterminate {\n  from {\n    background-position: 200% 0;\n  }\n  to {\n    background-position: -200% 0;\n  }\n}\n\n.table {\n  background-color: white;\n  color: #363636;\n}\n\n.table td,\n.table th {\n  border: 1px solid #dbdbdb;\n  border-width: 0 0 1px;\n  padding: 0.5em 0.75em;\n  vertical-align: top;\n}\n\n.table td.is-white,\n.table th.is-white {\n  background-color: white;\n  border-color: white;\n  color: #0a0a0a;\n}\n\n.table td.is-black,\n.table th.is-black {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  color: white;\n}\n\n.table td.is-light,\n.table th.is-light {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.table td.is-dark,\n.table th.is-dark {\n  background-color: #363636;\n  border-color: #363636;\n  color: #fff;\n}\n\n.table td.is-primary,\n.table th.is-primary {\n  background-color: #00d1b2;\n  border-color: #00d1b2;\n  color: #fff;\n}\n\n.table td.is-link,\n.table th.is-link {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n}\n\n.table td.is-info,\n.table th.is-info {\n  background-color: #3e8ed0;\n  border-color: #3e8ed0;\n  color: #fff;\n}\n\n.table td.is-success,\n.table th.is-success {\n  background-color: #48c78e;\n  border-color: #48c78e;\n  color: #fff;\n}\n\n.table td.is-warning,\n.table th.is-warning {\n  background-color: #ffe08a;\n  border-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.table td.is-danger,\n.table th.is-danger {\n  background-color: #f14668;\n  border-color: #f14668;\n  color: #fff;\n}\n\n.table td.is-narrow,\n.table th.is-narrow {\n  white-space: nowrap;\n  width: 1%;\n}\n\n.table td.is-selected,\n.table th.is-selected {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.table td.is-selected a,\n.table td.is-selected strong,\n.table th.is-selected a,\n.table th.is-selected strong {\n  color: currentColor;\n}\n\n.table td.is-vcentered,\n.table th.is-vcentered {\n  vertical-align: middle;\n}\n\n.table th {\n  color: #363636;\n}\n\n.table th:not([align]) {\n  text-align: left;\n}\n\n.table tr.is-selected {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.table tr.is-selected a,\n.table tr.is-selected strong {\n  color: currentColor;\n}\n\n.table tr.is-selected td,\n.table tr.is-selected th {\n  border-color: #fff;\n  color: currentColor;\n}\n\n.table thead {\n  background-color: transparent;\n}\n\n.table thead td,\n.table thead th {\n  border-width: 0 0 2px;\n  color: #363636;\n}\n\n.table tfoot {\n  background-color: transparent;\n}\n\n.table tfoot td,\n.table tfoot th {\n  border-width: 2px 0 0;\n  color: #363636;\n}\n\n.table tbody {\n  background-color: transparent;\n}\n\n.table tbody tr:last-child td,\n.table tbody tr:last-child th {\n  border-bottom-width: 0;\n}\n\n.table.is-bordered td,\n.table.is-bordered th {\n  border-width: 1px;\n}\n\n.table.is-bordered tr:last-child td,\n.table.is-bordered tr:last-child th {\n  border-bottom-width: 1px;\n}\n\n.table.is-fullwidth {\n  width: 100%;\n}\n\n.table.is-hoverable tbody tr:not(.is-selected):hover {\n  background-color: #fafafa;\n}\n\n.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover {\n  background-color: #fafafa;\n}\n\n.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even) {\n  background-color: whitesmoke;\n}\n\n.table.is-narrow td,\n.table.is-narrow th {\n  padding: 0.25em 0.5em;\n}\n\n.table.is-striped tbody tr:not(.is-selected):nth-child(even) {\n  background-color: #fafafa;\n}\n\n.table-container {\n  -webkit-overflow-scrolling: touch;\n  overflow: auto;\n  overflow-y: hidden;\n  max-width: 100%;\n}\n\n.tags {\n  align-items: center;\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n\n.tags .tag {\n  margin-bottom: 0.5rem;\n}\n\n.tags .tag:not(:last-child) {\n  margin-right: 0.5rem;\n}\n\n.tags:last-child {\n  margin-bottom: -0.5rem;\n}\n\n.tags:not(:last-child) {\n  margin-bottom: 1rem;\n}\n\n.tags.are-medium .tag:not(.is-normal):not(.is-large) {\n  font-size: 1rem;\n}\n\n.tags.are-large .tag:not(.is-normal):not(.is-medium) {\n  font-size: 1.25rem;\n}\n\n.tags.is-centered {\n  justify-content: center;\n}\n\n.tags.is-centered .tag {\n  margin-right: 0.25rem;\n  margin-left: 0.25rem;\n}\n\n.tags.is-right {\n  justify-content: flex-end;\n}\n\n.tags.is-right .tag:not(:first-child) {\n  margin-left: 0.5rem;\n}\n\n.tags.is-right .tag:not(:last-child) {\n  margin-right: 0;\n}\n\n.tags.has-addons .tag {\n  margin-right: 0;\n}\n\n.tags.has-addons .tag:not(:first-child) {\n  margin-left: 0;\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.tags.has-addons .tag:not(:last-child) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n\n.tag:not(body) {\n  align-items: center;\n  background-color: whitesmoke;\n  border-radius: 4px;\n  color: #4a4a4a;\n  display: inline-flex;\n  font-size: 0.75rem;\n  height: 2em;\n  justify-content: center;\n  line-height: 1.5;\n  padding-left: 0.75em;\n  padding-right: 0.75em;\n  white-space: nowrap;\n}\n\n.tag:not(body) .delete {\n  margin-left: 0.25rem;\n  margin-right: -0.375rem;\n}\n\n.tag:not(body).is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.tag:not(body).is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.tag:not(body).is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.tag:not(body).is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.tag:not(body).is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.tag:not(body).is-primary.is-light {\n  background-color: #ebfffc;\n  color: #00947e;\n}\n\n.tag:not(body).is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.tag:not(body).is-link.is-light {\n  background-color: #eff1fa;\n  color: #3850b7;\n}\n\n.tag:not(body).is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.tag:not(body).is-info.is-light {\n  background-color: #eff5fb;\n  color: #296fa8;\n}\n\n.tag:not(body).is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.tag:not(body).is-success.is-light {\n  background-color: #effaf5;\n  color: #257953;\n}\n\n.tag:not(body).is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.tag:not(body).is-warning.is-light {\n  background-color: #fffaeb;\n  color: #946c00;\n}\n\n.tag:not(body).is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.tag:not(body).is-danger.is-light {\n  background-color: #feecf0;\n  color: #cc0f35;\n}\n\n.tag:not(body).is-normal {\n  font-size: 0.75rem;\n}\n\n.tag:not(body).is-medium {\n  font-size: 1rem;\n}\n\n.tag:not(body).is-large {\n  font-size: 1.25rem;\n}\n\n.tag:not(body) .icon:first-child:not(:last-child) {\n  margin-left: -0.375em;\n  margin-right: 0.1875em;\n}\n\n.tag:not(body) .icon:last-child:not(:first-child) {\n  margin-left: 0.1875em;\n  margin-right: -0.375em;\n}\n\n.tag:not(body) .icon:first-child:last-child {\n  margin-left: -0.375em;\n  margin-right: -0.375em;\n}\n\n.tag:not(body).is-delete {\n  margin-left: 1px;\n  padding: 0;\n  position: relative;\n  width: 2em;\n}\n\n.tag:not(body).is-delete::before, .tag:not(body).is-delete::after {\n  background-color: currentColor;\n  content: \"\";\n  display: block;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translateX(-50%) translateY(-50%) rotate(45deg);\n  transform-origin: center center;\n}\n\n.tag:not(body).is-delete::before {\n  height: 1px;\n  width: 50%;\n}\n\n.tag:not(body).is-delete::after {\n  height: 50%;\n  width: 1px;\n}\n\n.tag:not(body).is-delete:hover, .tag:not(body).is-delete:focus {\n  background-color: #e8e8e8;\n}\n\n.tag:not(body).is-delete:active {\n  background-color: #dbdbdb;\n}\n\n.tag:not(body).is-rounded {\n  border-radius: 9999px;\n}\n\na.tag:hover {\n  text-decoration: underline;\n}\n\n.title,\n.subtitle {\n  word-break: break-word;\n}\n\n.title em,\n.title span,\n.subtitle em,\n.subtitle span {\n  font-weight: inherit;\n}\n\n.title sub,\n.subtitle sub {\n  font-size: 0.75em;\n}\n\n.title sup,\n.subtitle sup {\n  font-size: 0.75em;\n}\n\n.title .tag,\n.subtitle .tag {\n  vertical-align: middle;\n}\n\n.title {\n  color: #363636;\n  font-size: 2rem;\n  font-weight: 600;\n  line-height: 1.125;\n}\n\n.title strong {\n  color: inherit;\n  font-weight: inherit;\n}\n\n.title:not(.is-spaced) + .subtitle {\n  margin-top: -1.25rem;\n}\n\n.title.is-1 {\n  font-size: 3rem;\n}\n\n.title.is-2 {\n  font-size: 2.5rem;\n}\n\n.title.is-3 {\n  font-size: 2rem;\n}\n\n.title.is-4 {\n  font-size: 1.5rem;\n}\n\n.title.is-5 {\n  font-size: 1.25rem;\n}\n\n.title.is-6 {\n  font-size: 1rem;\n}\n\n.title.is-7 {\n  font-size: 0.75rem;\n}\n\n.subtitle {\n  color: #4a4a4a;\n  font-size: 1.25rem;\n  font-weight: 400;\n  line-height: 1.25;\n}\n\n.subtitle strong {\n  color: #363636;\n  font-weight: 600;\n}\n\n.subtitle:not(.is-spaced) + .title {\n  margin-top: -1.25rem;\n}\n\n.subtitle.is-1 {\n  font-size: 3rem;\n}\n\n.subtitle.is-2 {\n  font-size: 2.5rem;\n}\n\n.subtitle.is-3 {\n  font-size: 2rem;\n}\n\n.subtitle.is-4 {\n  font-size: 1.5rem;\n}\n\n.subtitle.is-5 {\n  font-size: 1.25rem;\n}\n\n.subtitle.is-6 {\n  font-size: 1rem;\n}\n\n.subtitle.is-7 {\n  font-size: 0.75rem;\n}\n\n.heading {\n  display: block;\n  font-size: 11px;\n  letter-spacing: 1px;\n  margin-bottom: 5px;\n  text-transform: uppercase;\n}\n\n.number {\n  align-items: center;\n  background-color: whitesmoke;\n  border-radius: 9999px;\n  display: inline-flex;\n  font-size: 1.25rem;\n  height: 2em;\n  justify-content: center;\n  margin-right: 1.5rem;\n  min-width: 2.5em;\n  padding: 0.25rem 0.5rem;\n  text-align: center;\n  vertical-align: top;\n}\n\n/* Bulma Form */\n.input, .textarea, .select select {\n  background-color: white;\n  border-color: #dbdbdb;\n  border-radius: 4px;\n  color: #363636;\n}\n\n.input::-moz-placeholder, .textarea::-moz-placeholder, .select select::-moz-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input::-webkit-input-placeholder, .textarea::-webkit-input-placeholder, .select select::-webkit-input-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input:-moz-placeholder, .textarea:-moz-placeholder, .select select:-moz-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input:-ms-input-placeholder, .textarea:-ms-input-placeholder, .select select:-ms-input-placeholder {\n  color: rgba(54, 54, 54, 0.3);\n}\n\n.input:hover, .textarea:hover, .select select:hover, .is-hovered.input, .is-hovered.textarea, .select select.is-hovered {\n  border-color: #b5b5b5;\n}\n\n.input:focus, .textarea:focus, .select select:focus, .is-focused.input, .is-focused.textarea, .select select.is-focused, .input:active, .textarea:active, .select select:active, .is-active.input, .is-active.textarea, .select select.is-active {\n  border-color: #485fc7;\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.input[disabled], .textarea[disabled], .select select[disabled],\nfieldset[disabled] .input,\nfieldset[disabled] .textarea,\nfieldset[disabled] .select select,\n.select fieldset[disabled] select {\n  background-color: whitesmoke;\n  border-color: whitesmoke;\n  box-shadow: none;\n  color: #7a7a7a;\n}\n\n.input[disabled]::-moz-placeholder, .textarea[disabled]::-moz-placeholder, .select select[disabled]::-moz-placeholder,\nfieldset[disabled] .input::-moz-placeholder,\nfieldset[disabled] .textarea::-moz-placeholder,\nfieldset[disabled] .select select::-moz-placeholder,\n.select fieldset[disabled] select::-moz-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input[disabled]::-webkit-input-placeholder, .textarea[disabled]::-webkit-input-placeholder, .select select[disabled]::-webkit-input-placeholder,\nfieldset[disabled] .input::-webkit-input-placeholder,\nfieldset[disabled] .textarea::-webkit-input-placeholder,\nfieldset[disabled] .select select::-webkit-input-placeholder,\n.select fieldset[disabled] select::-webkit-input-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input[disabled]:-moz-placeholder, .textarea[disabled]:-moz-placeholder, .select select[disabled]:-moz-placeholder,\nfieldset[disabled] .input:-moz-placeholder,\nfieldset[disabled] .textarea:-moz-placeholder,\nfieldset[disabled] .select select:-moz-placeholder,\n.select fieldset[disabled] select:-moz-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input[disabled]:-ms-input-placeholder, .textarea[disabled]:-ms-input-placeholder, .select select[disabled]:-ms-input-placeholder,\nfieldset[disabled] .input:-ms-input-placeholder,\nfieldset[disabled] .textarea:-ms-input-placeholder,\nfieldset[disabled] .select select:-ms-input-placeholder,\n.select fieldset[disabled] select:-ms-input-placeholder {\n  color: rgba(122, 122, 122, 0.3);\n}\n\n.input, .textarea {\n  box-shadow: inset 0 0.0625em 0.125em rgba(10, 10, 10, 0.05);\n  max-width: 100%;\n  width: 100%;\n}\n\n.input[readonly], .textarea[readonly] {\n  box-shadow: none;\n}\n\n.is-white.input, .is-white.textarea {\n  border-color: white;\n}\n\n.is-white.input:focus, .is-white.textarea:focus, .is-white.is-focused.input, .is-white.is-focused.textarea, .is-white.input:active, .is-white.textarea:active, .is-white.is-active.input, .is-white.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25);\n}\n\n.is-black.input, .is-black.textarea {\n  border-color: #0a0a0a;\n}\n\n.is-black.input:focus, .is-black.textarea:focus, .is-black.is-focused.input, .is-black.is-focused.textarea, .is-black.input:active, .is-black.textarea:active, .is-black.is-active.input, .is-black.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25);\n}\n\n.is-light.input, .is-light.textarea {\n  border-color: whitesmoke;\n}\n\n.is-light.input:focus, .is-light.textarea:focus, .is-light.is-focused.input, .is-light.is-focused.textarea, .is-light.input:active, .is-light.textarea:active, .is-light.is-active.input, .is-light.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25);\n}\n\n.is-dark.input, .is-dark.textarea {\n  border-color: #363636;\n}\n\n.is-dark.input:focus, .is-dark.textarea:focus, .is-dark.is-focused.input, .is-dark.is-focused.textarea, .is-dark.input:active, .is-dark.textarea:active, .is-dark.is-active.input, .is-dark.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25);\n}\n\n.is-primary.input, .is-primary.textarea {\n  border-color: #00d1b2;\n}\n\n.is-primary.input:focus, .is-primary.textarea:focus, .is-primary.is-focused.input, .is-primary.is-focused.textarea, .is-primary.input:active, .is-primary.textarea:active, .is-primary.is-active.input, .is-primary.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25);\n}\n\n.is-link.input, .is-link.textarea {\n  border-color: #485fc7;\n}\n\n.is-link.input:focus, .is-link.textarea:focus, .is-link.is-focused.input, .is-link.is-focused.textarea, .is-link.input:active, .is-link.textarea:active, .is-link.is-active.input, .is-link.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.is-info.input, .is-info.textarea {\n  border-color: #3e8ed0;\n}\n\n.is-info.input:focus, .is-info.textarea:focus, .is-info.is-focused.input, .is-info.is-focused.textarea, .is-info.input:active, .is-info.textarea:active, .is-info.is-active.input, .is-info.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(62, 142, 208, 0.25);\n}\n\n.is-success.input, .is-success.textarea {\n  border-color: #48c78e;\n}\n\n.is-success.input:focus, .is-success.textarea:focus, .is-success.is-focused.input, .is-success.is-focused.textarea, .is-success.input:active, .is-success.textarea:active, .is-success.is-active.input, .is-success.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(72, 199, 142, 0.25);\n}\n\n.is-warning.input, .is-warning.textarea {\n  border-color: #ffe08a;\n}\n\n.is-warning.input:focus, .is-warning.textarea:focus, .is-warning.is-focused.input, .is-warning.is-focused.textarea, .is-warning.input:active, .is-warning.textarea:active, .is-warning.is-active.input, .is-warning.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(255, 224, 138, 0.25);\n}\n\n.is-danger.input, .is-danger.textarea {\n  border-color: #f14668;\n}\n\n.is-danger.input:focus, .is-danger.textarea:focus, .is-danger.is-focused.input, .is-danger.is-focused.textarea, .is-danger.input:active, .is-danger.textarea:active, .is-danger.is-active.input, .is-danger.is-active.textarea {\n  box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25);\n}\n\n.is-small.input, .is-small.textarea {\n  border-radius: 2px;\n  font-size: 0.75rem;\n}\n\n.is-medium.input, .is-medium.textarea {\n  font-size: 1.25rem;\n}\n\n.is-large.input, .is-large.textarea {\n  font-size: 1.5rem;\n}\n\n.is-fullwidth.input, .is-fullwidth.textarea {\n  display: block;\n  width: 100%;\n}\n\n.is-inline.input, .is-inline.textarea {\n  display: inline;\n  width: auto;\n}\n\n.input.is-rounded {\n  border-radius: 9999px;\n  padding-left: calc(calc(0.75em - 1px) + 0.375em);\n  padding-right: calc(calc(0.75em - 1px) + 0.375em);\n}\n\n.input.is-static {\n  background-color: transparent;\n  border-color: transparent;\n  box-shadow: none;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n.textarea {\n  display: block;\n  max-width: 100%;\n  min-width: 100%;\n  padding: calc(0.75em - 1px);\n  resize: vertical;\n}\n\n.textarea:not([rows]) {\n  max-height: 40em;\n  min-height: 8em;\n}\n\n.textarea[rows] {\n  height: initial;\n}\n\n.textarea.has-fixed-size {\n  resize: none;\n}\n\n.checkbox, .radio {\n  cursor: pointer;\n  display: inline-block;\n  line-height: 1.25;\n  position: relative;\n}\n\n.checkbox input, .radio input {\n  cursor: pointer;\n}\n\n.checkbox:hover, .radio:hover {\n  color: #363636;\n}\n\n.checkbox[disabled], .radio[disabled],\nfieldset[disabled] .checkbox,\nfieldset[disabled] .radio,\n.checkbox input[disabled],\n.radio input[disabled] {\n  color: #7a7a7a;\n  cursor: not-allowed;\n}\n\n.radio + .radio {\n  margin-left: 0.5em;\n}\n\n.select {\n  display: inline-block;\n  max-width: 100%;\n  position: relative;\n  vertical-align: top;\n}\n\n.select:not(.is-multiple) {\n  height: 2.5em;\n}\n\n.select:not(.is-multiple):not(.is-loading)::after {\n  border-color: #485fc7;\n  right: 1.125em;\n  z-index: 4;\n}\n\n.select.is-rounded select {\n  border-radius: 9999px;\n  padding-left: 1em;\n}\n\n.select select {\n  cursor: pointer;\n  display: block;\n  font-size: 1em;\n  max-width: 100%;\n  outline: none;\n}\n\n.select select::-ms-expand {\n  display: none;\n}\n\n.select select[disabled]:hover,\nfieldset[disabled] .select select:hover {\n  border-color: whitesmoke;\n}\n\n.select select:not([multiple]) {\n  padding-right: 2.5em;\n}\n\n.select select[multiple] {\n  height: auto;\n  padding: 0;\n}\n\n.select select[multiple] option {\n  padding: 0.5em 1em;\n}\n\n.select:not(.is-multiple):not(.is-loading):hover::after {\n  border-color: #363636;\n}\n\n.select.is-white:not(:hover)::after {\n  border-color: white;\n}\n\n.select.is-white select {\n  border-color: white;\n}\n\n.select.is-white select:hover, .select.is-white select.is-hovered {\n  border-color: #f2f2f2;\n}\n\n.select.is-white select:focus, .select.is-white select.is-focused, .select.is-white select:active, .select.is-white select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25);\n}\n\n.select.is-black:not(:hover)::after {\n  border-color: #0a0a0a;\n}\n\n.select.is-black select {\n  border-color: #0a0a0a;\n}\n\n.select.is-black select:hover, .select.is-black select.is-hovered {\n  border-color: black;\n}\n\n.select.is-black select:focus, .select.is-black select.is-focused, .select.is-black select:active, .select.is-black select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25);\n}\n\n.select.is-light:not(:hover)::after {\n  border-color: whitesmoke;\n}\n\n.select.is-light select {\n  border-color: whitesmoke;\n}\n\n.select.is-light select:hover, .select.is-light select.is-hovered {\n  border-color: #e8e8e8;\n}\n\n.select.is-light select:focus, .select.is-light select.is-focused, .select.is-light select:active, .select.is-light select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25);\n}\n\n.select.is-dark:not(:hover)::after {\n  border-color: #363636;\n}\n\n.select.is-dark select {\n  border-color: #363636;\n}\n\n.select.is-dark select:hover, .select.is-dark select.is-hovered {\n  border-color: #292929;\n}\n\n.select.is-dark select:focus, .select.is-dark select.is-focused, .select.is-dark select:active, .select.is-dark select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25);\n}\n\n.select.is-primary:not(:hover)::after {\n  border-color: #00d1b2;\n}\n\n.select.is-primary select {\n  border-color: #00d1b2;\n}\n\n.select.is-primary select:hover, .select.is-primary select.is-hovered {\n  border-color: #00b89c;\n}\n\n.select.is-primary select:focus, .select.is-primary select.is-focused, .select.is-primary select:active, .select.is-primary select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25);\n}\n\n.select.is-link:not(:hover)::after {\n  border-color: #485fc7;\n}\n\n.select.is-link select {\n  border-color: #485fc7;\n}\n\n.select.is-link select:hover, .select.is-link select.is-hovered {\n  border-color: #3a51bb;\n}\n\n.select.is-link select:focus, .select.is-link select.is-focused, .select.is-link select:active, .select.is-link select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(72, 95, 199, 0.25);\n}\n\n.select.is-info:not(:hover)::after {\n  border-color: #3e8ed0;\n}\n\n.select.is-info select {\n  border-color: #3e8ed0;\n}\n\n.select.is-info select:hover, .select.is-info select.is-hovered {\n  border-color: #3082c5;\n}\n\n.select.is-info select:focus, .select.is-info select.is-focused, .select.is-info select:active, .select.is-info select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(62, 142, 208, 0.25);\n}\n\n.select.is-success:not(:hover)::after {\n  border-color: #48c78e;\n}\n\n.select.is-success select {\n  border-color: #48c78e;\n}\n\n.select.is-success select:hover, .select.is-success select.is-hovered {\n  border-color: #3abb81;\n}\n\n.select.is-success select:focus, .select.is-success select.is-focused, .select.is-success select:active, .select.is-success select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(72, 199, 142, 0.25);\n}\n\n.select.is-warning:not(:hover)::after {\n  border-color: #ffe08a;\n}\n\n.select.is-warning select {\n  border-color: #ffe08a;\n}\n\n.select.is-warning select:hover, .select.is-warning select.is-hovered {\n  border-color: #ffd970;\n}\n\n.select.is-warning select:focus, .select.is-warning select.is-focused, .select.is-warning select:active, .select.is-warning select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(255, 224, 138, 0.25);\n}\n\n.select.is-danger:not(:hover)::after {\n  border-color: #f14668;\n}\n\n.select.is-danger select {\n  border-color: #f14668;\n}\n\n.select.is-danger select:hover, .select.is-danger select.is-hovered {\n  border-color: #ef2e55;\n}\n\n.select.is-danger select:focus, .select.is-danger select.is-focused, .select.is-danger select:active, .select.is-danger select.is-active {\n  box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25);\n}\n\n.select.is-small {\n  border-radius: 2px;\n  font-size: 0.75rem;\n}\n\n.select.is-medium {\n  font-size: 1.25rem;\n}\n\n.select.is-large {\n  font-size: 1.5rem;\n}\n\n.select.is-disabled::after {\n  border-color: #7a7a7a !important;\n  opacity: 0.5;\n}\n\n.select.is-fullwidth {\n  width: 100%;\n}\n\n.select.is-fullwidth select {\n  width: 100%;\n}\n\n.select.is-loading::after {\n  margin-top: 0;\n  position: absolute;\n  right: 0.625em;\n  top: 0.625em;\n  transform: none;\n}\n\n.select.is-loading.is-small:after {\n  font-size: 0.75rem;\n}\n\n.select.is-loading.is-medium:after {\n  font-size: 1.25rem;\n}\n\n.select.is-loading.is-large:after {\n  font-size: 1.5rem;\n}\n\n.file {\n  align-items: stretch;\n  display: flex;\n  justify-content: flex-start;\n  position: relative;\n}\n\n.file.is-white .file-cta {\n  background-color: white;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.file.is-white:hover .file-cta, .file.is-white.is-hovered .file-cta {\n  background-color: #f9f9f9;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.file.is-white:focus .file-cta, .file.is-white.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(255, 255, 255, 0.25);\n  color: #0a0a0a;\n}\n\n.file.is-white:active .file-cta, .file.is-white.is-active .file-cta {\n  background-color: #f2f2f2;\n  border-color: transparent;\n  color: #0a0a0a;\n}\n\n.file.is-black .file-cta {\n  background-color: #0a0a0a;\n  border-color: transparent;\n  color: white;\n}\n\n.file.is-black:hover .file-cta, .file.is-black.is-hovered .file-cta {\n  background-color: #040404;\n  border-color: transparent;\n  color: white;\n}\n\n.file.is-black:focus .file-cta, .file.is-black.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(10, 10, 10, 0.25);\n  color: white;\n}\n\n.file.is-black:active .file-cta, .file.is-black.is-active .file-cta {\n  background-color: black;\n  border-color: transparent;\n  color: white;\n}\n\n.file.is-light .file-cta {\n  background-color: whitesmoke;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-light:hover .file-cta, .file.is-light.is-hovered .file-cta {\n  background-color: #eeeeee;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-light:focus .file-cta, .file.is-light.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(245, 245, 245, 0.25);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-light:active .file-cta, .file.is-light.is-active .file-cta {\n  background-color: #e8e8e8;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-dark .file-cta {\n  background-color: #363636;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-dark:hover .file-cta, .file.is-dark.is-hovered .file-cta {\n  background-color: #2f2f2f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-dark:focus .file-cta, .file.is-dark.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(54, 54, 54, 0.25);\n  color: #fff;\n}\n\n.file.is-dark:active .file-cta, .file.is-dark.is-active .file-cta {\n  background-color: #292929;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-primary .file-cta {\n  background-color: #00d1b2;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-primary:hover .file-cta, .file.is-primary.is-hovered .file-cta {\n  background-color: #00c4a7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-primary:focus .file-cta, .file.is-primary.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(0, 209, 178, 0.25);\n  color: #fff;\n}\n\n.file.is-primary:active .file-cta, .file.is-primary.is-active .file-cta {\n  background-color: #00b89c;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-link .file-cta {\n  background-color: #485fc7;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-link:hover .file-cta, .file.is-link.is-hovered .file-cta {\n  background-color: #3e56c4;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-link:focus .file-cta, .file.is-link.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(72, 95, 199, 0.25);\n  color: #fff;\n}\n\n.file.is-link:active .file-cta, .file.is-link.is-active .file-cta {\n  background-color: #3a51bb;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-info .file-cta {\n  background-color: #3e8ed0;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-info:hover .file-cta, .file.is-info.is-hovered .file-cta {\n  background-color: #3488ce;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-info:focus .file-cta, .file.is-info.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(62, 142, 208, 0.25);\n  color: #fff;\n}\n\n.file.is-info:active .file-cta, .file.is-info.is-active .file-cta {\n  background-color: #3082c5;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-success .file-cta {\n  background-color: #48c78e;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-success:hover .file-cta, .file.is-success.is-hovered .file-cta {\n  background-color: #3ec487;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-success:focus .file-cta, .file.is-success.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(72, 199, 142, 0.25);\n  color: #fff;\n}\n\n.file.is-success:active .file-cta, .file.is-success.is-active .file-cta {\n  background-color: #3abb81;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-warning .file-cta {\n  background-color: #ffe08a;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-warning:hover .file-cta, .file.is-warning.is-hovered .file-cta {\n  background-color: #ffdc7d;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-warning:focus .file-cta, .file.is-warning.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(255, 224, 138, 0.25);\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-warning:active .file-cta, .file.is-warning.is-active .file-cta {\n  background-color: #ffd970;\n  border-color: transparent;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.file.is-danger .file-cta {\n  background-color: #f14668;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-danger:hover .file-cta, .file.is-danger.is-hovered .file-cta {\n  background-color: #f03a5f;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-danger:focus .file-cta, .file.is-danger.is-focused .file-cta {\n  border-color: transparent;\n  box-shadow: 0 0 0.5em rgba(241, 70, 104, 0.25);\n  color: #fff;\n}\n\n.file.is-danger:active .file-cta, .file.is-danger.is-active .file-cta {\n  background-color: #ef2e55;\n  border-color: transparent;\n  color: #fff;\n}\n\n.file.is-small {\n  font-size: 0.75rem;\n}\n\n.file.is-normal {\n  font-size: 1rem;\n}\n\n.file.is-medium {\n  font-size: 1.25rem;\n}\n\n.file.is-medium .file-icon .fa {\n  font-size: 21px;\n}\n\n.file.is-large {\n  font-size: 1.5rem;\n}\n\n.file.is-large .file-icon .fa {\n  font-size: 28px;\n}\n\n.file.has-name .file-cta {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.file.has-name .file-name {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.file.has-name.is-empty .file-cta {\n  border-radius: 4px;\n}\n\n.file.has-name.is-empty .file-name {\n  display: none;\n}\n\n.file.is-boxed .file-label {\n  flex-direction: column;\n}\n\n.file.is-boxed .file-cta {\n  flex-direction: column;\n  height: auto;\n  padding: 1em 3em;\n}\n\n.file.is-boxed .file-name {\n  border-width: 0 1px 1px;\n}\n\n.file.is-boxed .file-icon {\n  height: 1.5em;\n  width: 1.5em;\n}\n\n.file.is-boxed .file-icon .fa {\n  font-size: 21px;\n}\n\n.file.is-boxed.is-small .file-icon .fa {\n  font-size: 14px;\n}\n\n.file.is-boxed.is-medium .file-icon .fa {\n  font-size: 28px;\n}\n\n.file.is-boxed.is-large .file-icon .fa {\n  font-size: 35px;\n}\n\n.file.is-boxed.has-name .file-cta {\n  border-radius: 4px 4px 0 0;\n}\n\n.file.is-boxed.has-name .file-name {\n  border-radius: 0 0 4px 4px;\n  border-width: 0 1px 1px;\n}\n\n.file.is-centered {\n  justify-content: center;\n}\n\n.file.is-fullwidth .file-label {\n  width: 100%;\n}\n\n.file.is-fullwidth .file-name {\n  flex-grow: 1;\n  max-width: none;\n}\n\n.file.is-right {\n  justify-content: flex-end;\n}\n\n.file.is-right .file-cta {\n  border-radius: 0 4px 4px 0;\n}\n\n.file.is-right .file-name {\n  border-radius: 4px 0 0 4px;\n  border-width: 1px 0 1px 1px;\n  order: -1;\n}\n\n.file-label {\n  align-items: stretch;\n  display: flex;\n  cursor: pointer;\n  justify-content: flex-start;\n  overflow: hidden;\n  position: relative;\n}\n\n.file-label:hover .file-cta {\n  background-color: #eeeeee;\n  color: #363636;\n}\n\n.file-label:hover .file-name {\n  border-color: #d5d5d5;\n}\n\n.file-label:active .file-cta {\n  background-color: #e8e8e8;\n  color: #363636;\n}\n\n.file-label:active .file-name {\n  border-color: #cfcfcf;\n}\n\n.file-input {\n  height: 100%;\n  left: 0;\n  opacity: 0;\n  outline: none;\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n\n.file-cta,\n.file-name {\n  border-color: #dbdbdb;\n  border-radius: 4px;\n  font-size: 1em;\n  padding-left: 1em;\n  padding-right: 1em;\n  white-space: nowrap;\n}\n\n.file-cta {\n  background-color: whitesmoke;\n  color: #4a4a4a;\n}\n\n.file-name {\n  border-color: #dbdbdb;\n  border-style: solid;\n  border-width: 1px 1px 1px 0;\n  display: block;\n  max-width: 16em;\n  overflow: hidden;\n  text-align: inherit;\n  text-overflow: ellipsis;\n}\n\n.file-icon {\n  align-items: center;\n  display: flex;\n  height: 1em;\n  justify-content: center;\n  margin-right: 0.5em;\n  width: 1em;\n}\n\n.file-icon .fa {\n  font-size: 14px;\n}\n\n.label {\n  color: #363636;\n  display: block;\n  font-size: 1rem;\n  font-weight: 700;\n}\n\n.label:not(:last-child) {\n  margin-bottom: 0.5em;\n}\n\n.label.is-small {\n  font-size: 0.75rem;\n}\n\n.label.is-medium {\n  font-size: 1.25rem;\n}\n\n.label.is-large {\n  font-size: 1.5rem;\n}\n\n.help {\n  display: block;\n  font-size: 0.75rem;\n  margin-top: 0.25rem;\n}\n\n.help.is-white {\n  color: white;\n}\n\n.help.is-black {\n  color: #0a0a0a;\n}\n\n.help.is-light {\n  color: whitesmoke;\n}\n\n.help.is-dark {\n  color: #363636;\n}\n\n.help.is-primary {\n  color: #00d1b2;\n}\n\n.help.is-link {\n  color: #485fc7;\n}\n\n.help.is-info {\n  color: #3e8ed0;\n}\n\n.help.is-success {\n  color: #48c78e;\n}\n\n.help.is-warning {\n  color: #ffe08a;\n}\n\n.help.is-danger {\n  color: #f14668;\n}\n\n.field:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.field.has-addons {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.field.has-addons .control:not(:last-child) {\n  margin-right: -1px;\n}\n\n.field.has-addons .control:not(:first-child):not(:last-child) .button,\n.field.has-addons .control:not(:first-child):not(:last-child) .input,\n.field.has-addons .control:not(:first-child):not(:last-child) .select select {\n  border-radius: 0;\n}\n\n.field.has-addons .control:first-child:not(:only-child) .button,\n.field.has-addons .control:first-child:not(:only-child) .input,\n.field.has-addons .control:first-child:not(:only-child) .select select {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.field.has-addons .control:last-child:not(:only-child) .button,\n.field.has-addons .control:last-child:not(:only-child) .input,\n.field.has-addons .control:last-child:not(:only-child) .select select {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.field.has-addons .control .button:not([disabled]):hover, .field.has-addons .control .button:not([disabled]).is-hovered,\n.field.has-addons .control .input:not([disabled]):hover,\n.field.has-addons .control .input:not([disabled]).is-hovered,\n.field.has-addons .control .select select:not([disabled]):hover,\n.field.has-addons .control .select select:not([disabled]).is-hovered {\n  z-index: 2;\n}\n\n.field.has-addons .control .button:not([disabled]):focus, .field.has-addons .control .button:not([disabled]).is-focused, .field.has-addons .control .button:not([disabled]):active, .field.has-addons .control .button:not([disabled]).is-active,\n.field.has-addons .control .input:not([disabled]):focus,\n.field.has-addons .control .input:not([disabled]).is-focused,\n.field.has-addons .control .input:not([disabled]):active,\n.field.has-addons .control .input:not([disabled]).is-active,\n.field.has-addons .control .select select:not([disabled]):focus,\n.field.has-addons .control .select select:not([disabled]).is-focused,\n.field.has-addons .control .select select:not([disabled]):active,\n.field.has-addons .control .select select:not([disabled]).is-active {\n  z-index: 3;\n}\n\n.field.has-addons .control .button:not([disabled]):focus:hover, .field.has-addons .control .button:not([disabled]).is-focused:hover, .field.has-addons .control .button:not([disabled]):active:hover, .field.has-addons .control .button:not([disabled]).is-active:hover,\n.field.has-addons .control .input:not([disabled]):focus:hover,\n.field.has-addons .control .input:not([disabled]).is-focused:hover,\n.field.has-addons .control .input:not([disabled]):active:hover,\n.field.has-addons .control .input:not([disabled]).is-active:hover,\n.field.has-addons .control .select select:not([disabled]):focus:hover,\n.field.has-addons .control .select select:not([disabled]).is-focused:hover,\n.field.has-addons .control .select select:not([disabled]):active:hover,\n.field.has-addons .control .select select:not([disabled]).is-active:hover {\n  z-index: 4;\n}\n\n.field.has-addons .control.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.field.has-addons.has-addons-centered {\n  justify-content: center;\n}\n\n.field.has-addons.has-addons-right {\n  justify-content: flex-end;\n}\n\n.field.has-addons.has-addons-fullwidth .control {\n  flex-grow: 1;\n  flex-shrink: 0;\n}\n\n.field.is-grouped {\n  display: flex;\n  justify-content: flex-start;\n}\n\n.field.is-grouped > .control {\n  flex-shrink: 0;\n}\n\n.field.is-grouped > .control:not(:last-child) {\n  margin-bottom: 0;\n  margin-right: 0.75rem;\n}\n\n.field.is-grouped > .control.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.field.is-grouped.is-grouped-centered {\n  justify-content: center;\n}\n\n.field.is-grouped.is-grouped-right {\n  justify-content: flex-end;\n}\n\n.field.is-grouped.is-grouped-multiline {\n  flex-wrap: wrap;\n}\n\n.field.is-grouped.is-grouped-multiline > .control:last-child, .field.is-grouped.is-grouped-multiline > .control:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.field.is-grouped.is-grouped-multiline:last-child {\n  margin-bottom: -0.75rem;\n}\n\n.field.is-grouped.is-grouped-multiline:not(:last-child) {\n  margin-bottom: 0;\n}\n\n@media screen and (min-width: 769px), print {\n  .field.is-horizontal {\n    display: flex;\n  }\n}\n\n.field-label .label {\n  font-size: inherit;\n}\n\n@media screen and (max-width: 768px) {\n  .field-label {\n    margin-bottom: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .field-label {\n    flex-basis: 0;\n    flex-grow: 1;\n    flex-shrink: 0;\n    margin-right: 1.5rem;\n    text-align: right;\n  }\n  .field-label.is-small {\n    font-size: 0.75rem;\n    padding-top: 0.375em;\n  }\n  .field-label.is-normal {\n    padding-top: 0.375em;\n  }\n  .field-label.is-medium {\n    font-size: 1.25rem;\n    padding-top: 0.375em;\n  }\n  .field-label.is-large {\n    font-size: 1.5rem;\n    padding-top: 0.375em;\n  }\n}\n\n.field-body .field .field {\n  margin-bottom: 0;\n}\n\n@media screen and (min-width: 769px), print {\n  .field-body {\n    display: flex;\n    flex-basis: 0;\n    flex-grow: 5;\n    flex-shrink: 1;\n  }\n  .field-body .field {\n    margin-bottom: 0;\n  }\n  .field-body > .field {\n    flex-shrink: 1;\n  }\n  .field-body > .field:not(.is-narrow) {\n    flex-grow: 1;\n  }\n  .field-body > .field:not(:last-child) {\n    margin-right: 0.75rem;\n  }\n}\n\n.control {\n  box-sizing: border-box;\n  clear: both;\n  font-size: 1rem;\n  position: relative;\n  text-align: inherit;\n}\n\n.control.has-icons-left .input:focus ~ .icon,\n.control.has-icons-left .select:focus ~ .icon, .control.has-icons-right .input:focus ~ .icon,\n.control.has-icons-right .select:focus ~ .icon {\n  color: #4a4a4a;\n}\n\n.control.has-icons-left .input.is-small ~ .icon,\n.control.has-icons-left .select.is-small ~ .icon, .control.has-icons-right .input.is-small ~ .icon,\n.control.has-icons-right .select.is-small ~ .icon {\n  font-size: 0.75rem;\n}\n\n.control.has-icons-left .input.is-medium ~ .icon,\n.control.has-icons-left .select.is-medium ~ .icon, .control.has-icons-right .input.is-medium ~ .icon,\n.control.has-icons-right .select.is-medium ~ .icon {\n  font-size: 1.25rem;\n}\n\n.control.has-icons-left .input.is-large ~ .icon,\n.control.has-icons-left .select.is-large ~ .icon, .control.has-icons-right .input.is-large ~ .icon,\n.control.has-icons-right .select.is-large ~ .icon {\n  font-size: 1.5rem;\n}\n\n.control.has-icons-left .icon, .control.has-icons-right .icon {\n  color: #dbdbdb;\n  height: 2.5em;\n  pointer-events: none;\n  position: absolute;\n  top: 0;\n  width: 2.5em;\n  z-index: 4;\n}\n\n.control.has-icons-left .input,\n.control.has-icons-left .select select {\n  padding-left: 2.5em;\n}\n\n.control.has-icons-left .icon.is-left {\n  left: 0;\n}\n\n.control.has-icons-right .input,\n.control.has-icons-right .select select {\n  padding-right: 2.5em;\n}\n\n.control.has-icons-right .icon.is-right {\n  right: 0;\n}\n\n.control.is-loading::after {\n  position: absolute !important;\n  right: 0.625em;\n  top: 0.625em;\n  z-index: 4;\n}\n\n.control.is-loading.is-small:after {\n  font-size: 0.75rem;\n}\n\n.control.is-loading.is-medium:after {\n  font-size: 1.25rem;\n}\n\n.control.is-loading.is-large:after {\n  font-size: 1.5rem;\n}\n\n/* Bulma Components */\n.breadcrumb {\n  font-size: 1rem;\n  white-space: nowrap;\n}\n\n.breadcrumb a {\n  align-items: center;\n  color: #485fc7;\n  display: flex;\n  justify-content: center;\n  padding: 0 0.75em;\n}\n\n.breadcrumb a:hover {\n  color: #363636;\n}\n\n.breadcrumb li {\n  align-items: center;\n  display: flex;\n}\n\n.breadcrumb li:first-child a {\n  padding-left: 0;\n}\n\n.breadcrumb li.is-active a {\n  color: #363636;\n  cursor: default;\n  pointer-events: none;\n}\n\n.breadcrumb li + li::before {\n  color: #b5b5b5;\n  content: \"\\0002f\";\n}\n\n.breadcrumb ul,\n.breadcrumb ol {\n  align-items: flex-start;\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n\n.breadcrumb .icon:first-child {\n  margin-right: 0.5em;\n}\n\n.breadcrumb .icon:last-child {\n  margin-left: 0.5em;\n}\n\n.breadcrumb.is-centered ol,\n.breadcrumb.is-centered ul {\n  justify-content: center;\n}\n\n.breadcrumb.is-right ol,\n.breadcrumb.is-right ul {\n  justify-content: flex-end;\n}\n\n.breadcrumb.is-small {\n  font-size: 0.75rem;\n}\n\n.breadcrumb.is-medium {\n  font-size: 1.25rem;\n}\n\n.breadcrumb.is-large {\n  font-size: 1.5rem;\n}\n\n.breadcrumb.has-arrow-separator li + li::before {\n  content: \"\\02192\";\n}\n\n.breadcrumb.has-bullet-separator li + li::before {\n  content: \"\\02022\";\n}\n\n.breadcrumb.has-dot-separator li + li::before {\n  content: \"\\000b7\";\n}\n\n.breadcrumb.has-succeeds-separator li + li::before {\n  content: \"\\0227B\";\n}\n\n.card {\n  background-color: white;\n  border-radius: 0.25rem;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  color: #4a4a4a;\n  max-width: 100%;\n  position: relative;\n}\n\n.card-header:first-child, .card-content:first-child, .card-footer:first-child {\n  border-top-left-radius: 0.25rem;\n  border-top-right-radius: 0.25rem;\n}\n\n.card-header:last-child, .card-content:last-child, .card-footer:last-child {\n  border-bottom-left-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n\n.card-header {\n  background-color: transparent;\n  align-items: stretch;\n  box-shadow: 0 0.125em 0.25em rgba(10, 10, 10, 0.1);\n  display: flex;\n}\n\n.card-header-title {\n  align-items: center;\n  color: #363636;\n  display: flex;\n  flex-grow: 1;\n  font-weight: 700;\n  padding: 0.75rem 1rem;\n}\n\n.card-header-title.is-centered {\n  justify-content: center;\n}\n\n.card-header-icon {\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n  background: none;\n  border: none;\n  color: currentColor;\n  font-family: inherit;\n  font-size: 1em;\n  margin: 0;\n  padding: 0;\n  align-items: center;\n  cursor: pointer;\n  display: flex;\n  justify-content: center;\n  padding: 0.75rem 1rem;\n}\n\n.card-image {\n  display: block;\n  position: relative;\n}\n\n.card-image:first-child img {\n  border-top-left-radius: 0.25rem;\n  border-top-right-radius: 0.25rem;\n}\n\n.card-image:last-child img {\n  border-bottom-left-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n\n.card-content {\n  background-color: transparent;\n  padding: 1.5rem;\n}\n\n.card-footer {\n  background-color: transparent;\n  border-top: 1px solid #ededed;\n  align-items: stretch;\n  display: flex;\n}\n\n.card-footer-item {\n  align-items: center;\n  display: flex;\n  flex-basis: 0;\n  flex-grow: 1;\n  flex-shrink: 0;\n  justify-content: center;\n  padding: 0.75rem;\n}\n\n.card-footer-item:not(:last-child) {\n  border-right: 1px solid #ededed;\n}\n\n.card .media:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.dropdown {\n  display: inline-flex;\n  position: relative;\n  vertical-align: top;\n}\n\n.dropdown.is-active .dropdown-menu, .dropdown.is-hoverable:hover .dropdown-menu {\n  display: block;\n}\n\n.dropdown.is-right .dropdown-menu {\n  left: auto;\n  right: 0;\n}\n\n.dropdown.is-up .dropdown-menu {\n  bottom: 100%;\n  padding-bottom: 4px;\n  padding-top: initial;\n  top: auto;\n}\n\n.dropdown-menu {\n  display: none;\n  left: 0;\n  min-width: 12rem;\n  padding-top: 4px;\n  position: absolute;\n  top: 100%;\n  z-index: 20;\n}\n\n.dropdown-content {\n  background-color: white;\n  border-radius: 4px;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  padding-bottom: 0.5rem;\n  padding-top: 0.5rem;\n}\n\n.dropdown-item {\n  color: #4a4a4a;\n  display: block;\n  font-size: 0.875rem;\n  line-height: 1.5;\n  padding: 0.375rem 1rem;\n  position: relative;\n}\n\na.dropdown-item,\nbutton.dropdown-item {\n  padding-right: 3rem;\n  text-align: inherit;\n  white-space: nowrap;\n  width: 100%;\n}\n\na.dropdown-item:hover,\nbutton.dropdown-item:hover {\n  background-color: whitesmoke;\n  color: #0a0a0a;\n}\n\na.dropdown-item.is-active,\nbutton.dropdown-item.is-active {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.dropdown-divider {\n  background-color: #ededed;\n  border: none;\n  display: block;\n  height: 1px;\n  margin: 0.5rem 0;\n}\n\n.level {\n  align-items: center;\n  justify-content: space-between;\n}\n\n.level code {\n  border-radius: 4px;\n}\n\n.level img {\n  display: inline-block;\n  vertical-align: top;\n}\n\n.level.is-mobile {\n  display: flex;\n}\n\n.level.is-mobile .level-left,\n.level.is-mobile .level-right {\n  display: flex;\n}\n\n.level.is-mobile .level-left + .level-right {\n  margin-top: 0;\n}\n\n.level.is-mobile .level-item:not(:last-child) {\n  margin-bottom: 0;\n  margin-right: 0.75rem;\n}\n\n.level.is-mobile .level-item:not(.is-narrow) {\n  flex-grow: 1;\n}\n\n@media screen and (min-width: 769px), print {\n  .level {\n    display: flex;\n  }\n  .level > .level-item:not(.is-narrow) {\n    flex-grow: 1;\n  }\n}\n\n.level-item {\n  align-items: center;\n  display: flex;\n  flex-basis: auto;\n  flex-grow: 0;\n  flex-shrink: 0;\n  justify-content: center;\n}\n\n.level-item .title,\n.level-item .subtitle {\n  margin-bottom: 0;\n}\n\n@media screen and (max-width: 768px) {\n  .level-item:not(:last-child) {\n    margin-bottom: 0.75rem;\n  }\n}\n\n.level-left,\n.level-right {\n  flex-basis: auto;\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.level-left .level-item.is-flexible,\n.level-right .level-item.is-flexible {\n  flex-grow: 1;\n}\n\n@media screen and (min-width: 769px), print {\n  .level-left .level-item:not(:last-child),\n  .level-right .level-item:not(:last-child) {\n    margin-right: 0.75rem;\n  }\n}\n\n.level-left {\n  align-items: center;\n  justify-content: flex-start;\n}\n\n@media screen and (max-width: 768px) {\n  .level-left + .level-right {\n    margin-top: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .level-left {\n    display: flex;\n  }\n}\n\n.level-right {\n  align-items: center;\n  justify-content: flex-end;\n}\n\n@media screen and (min-width: 769px), print {\n  .level-right {\n    display: flex;\n  }\n}\n\n.media {\n  align-items: flex-start;\n  display: flex;\n  text-align: inherit;\n}\n\n.media .content:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.media .media {\n  border-top: 1px solid rgba(219, 219, 219, 0.5);\n  display: flex;\n  padding-top: 0.75rem;\n}\n\n.media .media .content:not(:last-child),\n.media .media .control:not(:last-child) {\n  margin-bottom: 0.5rem;\n}\n\n.media .media .media {\n  padding-top: 0.5rem;\n}\n\n.media .media .media + .media {\n  margin-top: 0.5rem;\n}\n\n.media + .media {\n  border-top: 1px solid rgba(219, 219, 219, 0.5);\n  margin-top: 1rem;\n  padding-top: 1rem;\n}\n\n.media.is-large + .media {\n  margin-top: 1.5rem;\n  padding-top: 1.5rem;\n}\n\n.media-left,\n.media-right {\n  flex-basis: auto;\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.media-left {\n  margin-right: 1rem;\n}\n\n.media-right {\n  margin-left: 1rem;\n}\n\n.media-content {\n  flex-basis: auto;\n  flex-grow: 1;\n  flex-shrink: 1;\n  text-align: inherit;\n}\n\n@media screen and (max-width: 768px) {\n  .media-content {\n    overflow-x: auto;\n  }\n}\n\n.menu {\n  font-size: 1rem;\n}\n\n.menu.is-small {\n  font-size: 0.75rem;\n}\n\n.menu.is-medium {\n  font-size: 1.25rem;\n}\n\n.menu.is-large {\n  font-size: 1.5rem;\n}\n\n.menu-list {\n  line-height: 1.25;\n}\n\n.menu-list a {\n  border-radius: 2px;\n  color: #4a4a4a;\n  display: block;\n  padding: 0.5em 0.75em;\n}\n\n.menu-list a:hover {\n  background-color: whitesmoke;\n  color: #363636;\n}\n\n.menu-list a.is-active {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.menu-list li ul {\n  border-left: 1px solid #dbdbdb;\n  margin: 0.75em;\n  padding-left: 0.75em;\n}\n\n.menu-label {\n  color: #7a7a7a;\n  font-size: 0.75em;\n  letter-spacing: 0.1em;\n  text-transform: uppercase;\n}\n\n.menu-label:not(:first-child) {\n  margin-top: 1em;\n}\n\n.menu-label:not(:last-child) {\n  margin-bottom: 1em;\n}\n\n.message {\n  background-color: whitesmoke;\n  border-radius: 4px;\n  font-size: 1rem;\n}\n\n.message strong {\n  color: currentColor;\n}\n\n.message a:not(.button):not(.tag):not(.dropdown-item) {\n  color: currentColor;\n  text-decoration: underline;\n}\n\n.message.is-small {\n  font-size: 0.75rem;\n}\n\n.message.is-medium {\n  font-size: 1.25rem;\n}\n\n.message.is-large {\n  font-size: 1.5rem;\n}\n\n.message.is-white {\n  background-color: white;\n}\n\n.message.is-white .message-header {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.message.is-white .message-body {\n  border-color: white;\n}\n\n.message.is-black {\n  background-color: #fafafa;\n}\n\n.message.is-black .message-header {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.message.is-black .message-body {\n  border-color: #0a0a0a;\n}\n\n.message.is-light {\n  background-color: #fafafa;\n}\n\n.message.is-light .message-header {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.message.is-light .message-body {\n  border-color: whitesmoke;\n}\n\n.message.is-dark {\n  background-color: #fafafa;\n}\n\n.message.is-dark .message-header {\n  background-color: #363636;\n  color: #fff;\n}\n\n.message.is-dark .message-body {\n  border-color: #363636;\n}\n\n.message.is-primary {\n  background-color: #ebfffc;\n}\n\n.message.is-primary .message-header {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.message.is-primary .message-body {\n  border-color: #00d1b2;\n  color: #00947e;\n}\n\n.message.is-link {\n  background-color: #eff1fa;\n}\n\n.message.is-link .message-header {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.message.is-link .message-body {\n  border-color: #485fc7;\n  color: #3850b7;\n}\n\n.message.is-info {\n  background-color: #eff5fb;\n}\n\n.message.is-info .message-header {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.message.is-info .message-body {\n  border-color: #3e8ed0;\n  color: #296fa8;\n}\n\n.message.is-success {\n  background-color: #effaf5;\n}\n\n.message.is-success .message-header {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.message.is-success .message-body {\n  border-color: #48c78e;\n  color: #257953;\n}\n\n.message.is-warning {\n  background-color: #fffaeb;\n}\n\n.message.is-warning .message-header {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.message.is-warning .message-body {\n  border-color: #ffe08a;\n  color: #946c00;\n}\n\n.message.is-danger {\n  background-color: #feecf0;\n}\n\n.message.is-danger .message-header {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.message.is-danger .message-body {\n  border-color: #f14668;\n  color: #cc0f35;\n}\n\n.message-header {\n  align-items: center;\n  background-color: #4a4a4a;\n  border-radius: 4px 4px 0 0;\n  color: #fff;\n  display: flex;\n  font-weight: 700;\n  justify-content: space-between;\n  line-height: 1.25;\n  padding: 0.75em 1em;\n  position: relative;\n}\n\n.message-header .delete {\n  flex-grow: 0;\n  flex-shrink: 0;\n  margin-left: 0.75em;\n}\n\n.message-header + .message-body {\n  border-width: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.message-body {\n  border-color: #dbdbdb;\n  border-radius: 4px;\n  border-style: solid;\n  border-width: 0 0 0 4px;\n  color: #4a4a4a;\n  padding: 1.25em 1.5em;\n}\n\n.message-body code,\n.message-body pre {\n  background-color: white;\n}\n\n.message-body pre code {\n  background-color: transparent;\n}\n\n.modal {\n  align-items: center;\n  display: none;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  position: fixed;\n  z-index: 40;\n}\n\n.modal.is-active {\n  display: flex;\n}\n\n.modal-background {\n  background-color: rgba(10, 10, 10, 0.86);\n}\n\n.modal-content,\n.modal-card {\n  margin: 0 20px;\n  max-height: calc(100vh - 160px);\n  overflow: auto;\n  position: relative;\n  width: 100%;\n}\n\n@media screen and (min-width: 769px) {\n  .modal-content,\n  .modal-card {\n    margin: 0 auto;\n    max-height: calc(100vh - 40px);\n    width: 640px;\n  }\n}\n\n.modal-close {\n  background: none;\n  height: 40px;\n  position: fixed;\n  right: 20px;\n  top: 20px;\n  width: 40px;\n}\n\n.modal-card {\n  display: flex;\n  flex-direction: column;\n  max-height: calc(100vh - 40px);\n  overflow: hidden;\n  -ms-overflow-y: visible;\n}\n\n.modal-card-head,\n.modal-card-foot {\n  align-items: center;\n  background-color: whitesmoke;\n  display: flex;\n  flex-shrink: 0;\n  justify-content: flex-start;\n  padding: 20px;\n  position: relative;\n}\n\n.modal-card-head {\n  border-bottom: 1px solid #dbdbdb;\n  border-top-left-radius: 6px;\n  border-top-right-radius: 6px;\n}\n\n.modal-card-title {\n  color: #363636;\n  flex-grow: 1;\n  flex-shrink: 0;\n  font-size: 1.5rem;\n  line-height: 1;\n}\n\n.modal-card-foot {\n  border-bottom-left-radius: 6px;\n  border-bottom-right-radius: 6px;\n  border-top: 1px solid #dbdbdb;\n}\n\n.modal-card-foot .button:not(:last-child) {\n  margin-right: 0.5em;\n}\n\n.modal-card-body {\n  -webkit-overflow-scrolling: touch;\n  background-color: white;\n  flex-grow: 1;\n  flex-shrink: 1;\n  overflow: auto;\n  padding: 20px;\n}\n\n.navbar {\n  background-color: white;\n  min-height: 3.25rem;\n  position: relative;\n  z-index: 30;\n}\n\n.navbar.is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-brand > .navbar-item,\n.navbar.is-white .navbar-brand .navbar-link {\n  color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-brand > a.navbar-item:focus, .navbar.is-white .navbar-brand > a.navbar-item:hover, .navbar.is-white .navbar-brand > a.navbar-item.is-active,\n.navbar.is-white .navbar-brand .navbar-link:focus,\n.navbar.is-white .navbar-brand .navbar-link:hover,\n.navbar.is-white .navbar-brand .navbar-link.is-active {\n  background-color: #f2f2f2;\n  color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-brand .navbar-link::after {\n  border-color: #0a0a0a;\n}\n\n.navbar.is-white .navbar-burger {\n  color: #0a0a0a;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-white .navbar-start > .navbar-item,\n  .navbar.is-white .navbar-start .navbar-link,\n  .navbar.is-white .navbar-end > .navbar-item,\n  .navbar.is-white .navbar-end .navbar-link {\n    color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-start > a.navbar-item:focus, .navbar.is-white .navbar-start > a.navbar-item:hover, .navbar.is-white .navbar-start > a.navbar-item.is-active,\n  .navbar.is-white .navbar-start .navbar-link:focus,\n  .navbar.is-white .navbar-start .navbar-link:hover,\n  .navbar.is-white .navbar-start .navbar-link.is-active,\n  .navbar.is-white .navbar-end > a.navbar-item:focus,\n  .navbar.is-white .navbar-end > a.navbar-item:hover,\n  .navbar.is-white .navbar-end > a.navbar-item.is-active,\n  .navbar.is-white .navbar-end .navbar-link:focus,\n  .navbar.is-white .navbar-end .navbar-link:hover,\n  .navbar.is-white .navbar-end .navbar-link.is-active {\n    background-color: #f2f2f2;\n    color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-start .navbar-link::after,\n  .navbar.is-white .navbar-end .navbar-link::after {\n    border-color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #f2f2f2;\n    color: #0a0a0a;\n  }\n  .navbar.is-white .navbar-dropdown a.navbar-item.is-active {\n    background-color: white;\n    color: #0a0a0a;\n  }\n}\n\n.navbar.is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.navbar.is-black .navbar-brand > .navbar-item,\n.navbar.is-black .navbar-brand .navbar-link {\n  color: white;\n}\n\n.navbar.is-black .navbar-brand > a.navbar-item:focus, .navbar.is-black .navbar-brand > a.navbar-item:hover, .navbar.is-black .navbar-brand > a.navbar-item.is-active,\n.navbar.is-black .navbar-brand .navbar-link:focus,\n.navbar.is-black .navbar-brand .navbar-link:hover,\n.navbar.is-black .navbar-brand .navbar-link.is-active {\n  background-color: black;\n  color: white;\n}\n\n.navbar.is-black .navbar-brand .navbar-link::after {\n  border-color: white;\n}\n\n.navbar.is-black .navbar-burger {\n  color: white;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-black .navbar-start > .navbar-item,\n  .navbar.is-black .navbar-start .navbar-link,\n  .navbar.is-black .navbar-end > .navbar-item,\n  .navbar.is-black .navbar-end .navbar-link {\n    color: white;\n  }\n  .navbar.is-black .navbar-start > a.navbar-item:focus, .navbar.is-black .navbar-start > a.navbar-item:hover, .navbar.is-black .navbar-start > a.navbar-item.is-active,\n  .navbar.is-black .navbar-start .navbar-link:focus,\n  .navbar.is-black .navbar-start .navbar-link:hover,\n  .navbar.is-black .navbar-start .navbar-link.is-active,\n  .navbar.is-black .navbar-end > a.navbar-item:focus,\n  .navbar.is-black .navbar-end > a.navbar-item:hover,\n  .navbar.is-black .navbar-end > a.navbar-item.is-active,\n  .navbar.is-black .navbar-end .navbar-link:focus,\n  .navbar.is-black .navbar-end .navbar-link:hover,\n  .navbar.is-black .navbar-end .navbar-link.is-active {\n    background-color: black;\n    color: white;\n  }\n  .navbar.is-black .navbar-start .navbar-link::after,\n  .navbar.is-black .navbar-end .navbar-link::after {\n    border-color: white;\n  }\n  .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: black;\n    color: white;\n  }\n  .navbar.is-black .navbar-dropdown a.navbar-item.is-active {\n    background-color: #0a0a0a;\n    color: white;\n  }\n}\n\n.navbar.is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-brand > .navbar-item,\n.navbar.is-light .navbar-brand .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-brand > a.navbar-item:focus, .navbar.is-light .navbar-brand > a.navbar-item:hover, .navbar.is-light .navbar-brand > a.navbar-item.is-active,\n.navbar.is-light .navbar-brand .navbar-link:focus,\n.navbar.is-light .navbar-brand .navbar-link:hover,\n.navbar.is-light .navbar-brand .navbar-link.is-active {\n  background-color: #e8e8e8;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-brand .navbar-link::after {\n  border-color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-light .navbar-burger {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-light .navbar-start > .navbar-item,\n  .navbar.is-light .navbar-start .navbar-link,\n  .navbar.is-light .navbar-end > .navbar-item,\n  .navbar.is-light .navbar-end .navbar-link {\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-start > a.navbar-item:focus, .navbar.is-light .navbar-start > a.navbar-item:hover, .navbar.is-light .navbar-start > a.navbar-item.is-active,\n  .navbar.is-light .navbar-start .navbar-link:focus,\n  .navbar.is-light .navbar-start .navbar-link:hover,\n  .navbar.is-light .navbar-start .navbar-link.is-active,\n  .navbar.is-light .navbar-end > a.navbar-item:focus,\n  .navbar.is-light .navbar-end > a.navbar-item:hover,\n  .navbar.is-light .navbar-end > a.navbar-item.is-active,\n  .navbar.is-light .navbar-end .navbar-link:focus,\n  .navbar.is-light .navbar-end .navbar-link:hover,\n  .navbar.is-light .navbar-end .navbar-link.is-active {\n    background-color: #e8e8e8;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-start .navbar-link::after,\n  .navbar.is-light .navbar-end .navbar-link::after {\n    border-color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #e8e8e8;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-light .navbar-dropdown a.navbar-item.is-active {\n    background-color: whitesmoke;\n    color: rgba(0, 0, 0, 0.7);\n  }\n}\n\n.navbar.is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.navbar.is-dark .navbar-brand > .navbar-item,\n.navbar.is-dark .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-dark .navbar-brand > a.navbar-item:focus, .navbar.is-dark .navbar-brand > a.navbar-item:hover, .navbar.is-dark .navbar-brand > a.navbar-item.is-active,\n.navbar.is-dark .navbar-brand .navbar-link:focus,\n.navbar.is-dark .navbar-brand .navbar-link:hover,\n.navbar.is-dark .navbar-brand .navbar-link.is-active {\n  background-color: #292929;\n  color: #fff;\n}\n\n.navbar.is-dark .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-dark .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-dark .navbar-start > .navbar-item,\n  .navbar.is-dark .navbar-start .navbar-link,\n  .navbar.is-dark .navbar-end > .navbar-item,\n  .navbar.is-dark .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-dark .navbar-start > a.navbar-item:focus, .navbar.is-dark .navbar-start > a.navbar-item:hover, .navbar.is-dark .navbar-start > a.navbar-item.is-active,\n  .navbar.is-dark .navbar-start .navbar-link:focus,\n  .navbar.is-dark .navbar-start .navbar-link:hover,\n  .navbar.is-dark .navbar-start .navbar-link.is-active,\n  .navbar.is-dark .navbar-end > a.navbar-item:focus,\n  .navbar.is-dark .navbar-end > a.navbar-item:hover,\n  .navbar.is-dark .navbar-end > a.navbar-item.is-active,\n  .navbar.is-dark .navbar-end .navbar-link:focus,\n  .navbar.is-dark .navbar-end .navbar-link:hover,\n  .navbar.is-dark .navbar-end .navbar-link.is-active {\n    background-color: #292929;\n    color: #fff;\n  }\n  .navbar.is-dark .navbar-start .navbar-link::after,\n  .navbar.is-dark .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #292929;\n    color: #fff;\n  }\n  .navbar.is-dark .navbar-dropdown a.navbar-item.is-active {\n    background-color: #363636;\n    color: #fff;\n  }\n}\n\n.navbar.is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.navbar.is-primary .navbar-brand > .navbar-item,\n.navbar.is-primary .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-primary .navbar-brand > a.navbar-item:focus, .navbar.is-primary .navbar-brand > a.navbar-item:hover, .navbar.is-primary .navbar-brand > a.navbar-item.is-active,\n.navbar.is-primary .navbar-brand .navbar-link:focus,\n.navbar.is-primary .navbar-brand .navbar-link:hover,\n.navbar.is-primary .navbar-brand .navbar-link.is-active {\n  background-color: #00b89c;\n  color: #fff;\n}\n\n.navbar.is-primary .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-primary .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-primary .navbar-start > .navbar-item,\n  .navbar.is-primary .navbar-start .navbar-link,\n  .navbar.is-primary .navbar-end > .navbar-item,\n  .navbar.is-primary .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-primary .navbar-start > a.navbar-item:focus, .navbar.is-primary .navbar-start > a.navbar-item:hover, .navbar.is-primary .navbar-start > a.navbar-item.is-active,\n  .navbar.is-primary .navbar-start .navbar-link:focus,\n  .navbar.is-primary .navbar-start .navbar-link:hover,\n  .navbar.is-primary .navbar-start .navbar-link.is-active,\n  .navbar.is-primary .navbar-end > a.navbar-item:focus,\n  .navbar.is-primary .navbar-end > a.navbar-item:hover,\n  .navbar.is-primary .navbar-end > a.navbar-item.is-active,\n  .navbar.is-primary .navbar-end .navbar-link:focus,\n  .navbar.is-primary .navbar-end .navbar-link:hover,\n  .navbar.is-primary .navbar-end .navbar-link.is-active {\n    background-color: #00b89c;\n    color: #fff;\n  }\n  .navbar.is-primary .navbar-start .navbar-link::after,\n  .navbar.is-primary .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #00b89c;\n    color: #fff;\n  }\n  .navbar.is-primary .navbar-dropdown a.navbar-item.is-active {\n    background-color: #00d1b2;\n    color: #fff;\n  }\n}\n\n.navbar.is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.navbar.is-link .navbar-brand > .navbar-item,\n.navbar.is-link .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-link .navbar-brand > a.navbar-item:focus, .navbar.is-link .navbar-brand > a.navbar-item:hover, .navbar.is-link .navbar-brand > a.navbar-item.is-active,\n.navbar.is-link .navbar-brand .navbar-link:focus,\n.navbar.is-link .navbar-brand .navbar-link:hover,\n.navbar.is-link .navbar-brand .navbar-link.is-active {\n  background-color: #3a51bb;\n  color: #fff;\n}\n\n.navbar.is-link .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-link .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-link .navbar-start > .navbar-item,\n  .navbar.is-link .navbar-start .navbar-link,\n  .navbar.is-link .navbar-end > .navbar-item,\n  .navbar.is-link .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-link .navbar-start > a.navbar-item:focus, .navbar.is-link .navbar-start > a.navbar-item:hover, .navbar.is-link .navbar-start > a.navbar-item.is-active,\n  .navbar.is-link .navbar-start .navbar-link:focus,\n  .navbar.is-link .navbar-start .navbar-link:hover,\n  .navbar.is-link .navbar-start .navbar-link.is-active,\n  .navbar.is-link .navbar-end > a.navbar-item:focus,\n  .navbar.is-link .navbar-end > a.navbar-item:hover,\n  .navbar.is-link .navbar-end > a.navbar-item.is-active,\n  .navbar.is-link .navbar-end .navbar-link:focus,\n  .navbar.is-link .navbar-end .navbar-link:hover,\n  .navbar.is-link .navbar-end .navbar-link.is-active {\n    background-color: #3a51bb;\n    color: #fff;\n  }\n  .navbar.is-link .navbar-start .navbar-link::after,\n  .navbar.is-link .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #3a51bb;\n    color: #fff;\n  }\n  .navbar.is-link .navbar-dropdown a.navbar-item.is-active {\n    background-color: #485fc7;\n    color: #fff;\n  }\n}\n\n.navbar.is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.navbar.is-info .navbar-brand > .navbar-item,\n.navbar.is-info .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-info .navbar-brand > a.navbar-item:focus, .navbar.is-info .navbar-brand > a.navbar-item:hover, .navbar.is-info .navbar-brand > a.navbar-item.is-active,\n.navbar.is-info .navbar-brand .navbar-link:focus,\n.navbar.is-info .navbar-brand .navbar-link:hover,\n.navbar.is-info .navbar-brand .navbar-link.is-active {\n  background-color: #3082c5;\n  color: #fff;\n}\n\n.navbar.is-info .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-info .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-info .navbar-start > .navbar-item,\n  .navbar.is-info .navbar-start .navbar-link,\n  .navbar.is-info .navbar-end > .navbar-item,\n  .navbar.is-info .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-info .navbar-start > a.navbar-item:focus, .navbar.is-info .navbar-start > a.navbar-item:hover, .navbar.is-info .navbar-start > a.navbar-item.is-active,\n  .navbar.is-info .navbar-start .navbar-link:focus,\n  .navbar.is-info .navbar-start .navbar-link:hover,\n  .navbar.is-info .navbar-start .navbar-link.is-active,\n  .navbar.is-info .navbar-end > a.navbar-item:focus,\n  .navbar.is-info .navbar-end > a.navbar-item:hover,\n  .navbar.is-info .navbar-end > a.navbar-item.is-active,\n  .navbar.is-info .navbar-end .navbar-link:focus,\n  .navbar.is-info .navbar-end .navbar-link:hover,\n  .navbar.is-info .navbar-end .navbar-link.is-active {\n    background-color: #3082c5;\n    color: #fff;\n  }\n  .navbar.is-info .navbar-start .navbar-link::after,\n  .navbar.is-info .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #3082c5;\n    color: #fff;\n  }\n  .navbar.is-info .navbar-dropdown a.navbar-item.is-active {\n    background-color: #3e8ed0;\n    color: #fff;\n  }\n}\n\n.navbar.is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.navbar.is-success .navbar-brand > .navbar-item,\n.navbar.is-success .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-success .navbar-brand > a.navbar-item:focus, .navbar.is-success .navbar-brand > a.navbar-item:hover, .navbar.is-success .navbar-brand > a.navbar-item.is-active,\n.navbar.is-success .navbar-brand .navbar-link:focus,\n.navbar.is-success .navbar-brand .navbar-link:hover,\n.navbar.is-success .navbar-brand .navbar-link.is-active {\n  background-color: #3abb81;\n  color: #fff;\n}\n\n.navbar.is-success .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-success .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-success .navbar-start > .navbar-item,\n  .navbar.is-success .navbar-start .navbar-link,\n  .navbar.is-success .navbar-end > .navbar-item,\n  .navbar.is-success .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-success .navbar-start > a.navbar-item:focus, .navbar.is-success .navbar-start > a.navbar-item:hover, .navbar.is-success .navbar-start > a.navbar-item.is-active,\n  .navbar.is-success .navbar-start .navbar-link:focus,\n  .navbar.is-success .navbar-start .navbar-link:hover,\n  .navbar.is-success .navbar-start .navbar-link.is-active,\n  .navbar.is-success .navbar-end > a.navbar-item:focus,\n  .navbar.is-success .navbar-end > a.navbar-item:hover,\n  .navbar.is-success .navbar-end > a.navbar-item.is-active,\n  .navbar.is-success .navbar-end .navbar-link:focus,\n  .navbar.is-success .navbar-end .navbar-link:hover,\n  .navbar.is-success .navbar-end .navbar-link.is-active {\n    background-color: #3abb81;\n    color: #fff;\n  }\n  .navbar.is-success .navbar-start .navbar-link::after,\n  .navbar.is-success .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #3abb81;\n    color: #fff;\n  }\n  .navbar.is-success .navbar-dropdown a.navbar-item.is-active {\n    background-color: #48c78e;\n    color: #fff;\n  }\n}\n\n.navbar.is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-brand > .navbar-item,\n.navbar.is-warning .navbar-brand .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-brand > a.navbar-item:focus, .navbar.is-warning .navbar-brand > a.navbar-item:hover, .navbar.is-warning .navbar-brand > a.navbar-item.is-active,\n.navbar.is-warning .navbar-brand .navbar-link:focus,\n.navbar.is-warning .navbar-brand .navbar-link:hover,\n.navbar.is-warning .navbar-brand .navbar-link.is-active {\n  background-color: #ffd970;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-brand .navbar-link::after {\n  border-color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar.is-warning .navbar-burger {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-warning .navbar-start > .navbar-item,\n  .navbar.is-warning .navbar-start .navbar-link,\n  .navbar.is-warning .navbar-end > .navbar-item,\n  .navbar.is-warning .navbar-end .navbar-link {\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-start > a.navbar-item:focus, .navbar.is-warning .navbar-start > a.navbar-item:hover, .navbar.is-warning .navbar-start > a.navbar-item.is-active,\n  .navbar.is-warning .navbar-start .navbar-link:focus,\n  .navbar.is-warning .navbar-start .navbar-link:hover,\n  .navbar.is-warning .navbar-start .navbar-link.is-active,\n  .navbar.is-warning .navbar-end > a.navbar-item:focus,\n  .navbar.is-warning .navbar-end > a.navbar-item:hover,\n  .navbar.is-warning .navbar-end > a.navbar-item.is-active,\n  .navbar.is-warning .navbar-end .navbar-link:focus,\n  .navbar.is-warning .navbar-end .navbar-link:hover,\n  .navbar.is-warning .navbar-end .navbar-link.is-active {\n    background-color: #ffd970;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-start .navbar-link::after,\n  .navbar.is-warning .navbar-end .navbar-link::after {\n    border-color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #ffd970;\n    color: rgba(0, 0, 0, 0.7);\n  }\n  .navbar.is-warning .navbar-dropdown a.navbar-item.is-active {\n    background-color: #ffe08a;\n    color: rgba(0, 0, 0, 0.7);\n  }\n}\n\n.navbar.is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.navbar.is-danger .navbar-brand > .navbar-item,\n.navbar.is-danger .navbar-brand .navbar-link {\n  color: #fff;\n}\n\n.navbar.is-danger .navbar-brand > a.navbar-item:focus, .navbar.is-danger .navbar-brand > a.navbar-item:hover, .navbar.is-danger .navbar-brand > a.navbar-item.is-active,\n.navbar.is-danger .navbar-brand .navbar-link:focus,\n.navbar.is-danger .navbar-brand .navbar-link:hover,\n.navbar.is-danger .navbar-brand .navbar-link.is-active {\n  background-color: #ef2e55;\n  color: #fff;\n}\n\n.navbar.is-danger .navbar-brand .navbar-link::after {\n  border-color: #fff;\n}\n\n.navbar.is-danger .navbar-burger {\n  color: #fff;\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar.is-danger .navbar-start > .navbar-item,\n  .navbar.is-danger .navbar-start .navbar-link,\n  .navbar.is-danger .navbar-end > .navbar-item,\n  .navbar.is-danger .navbar-end .navbar-link {\n    color: #fff;\n  }\n  .navbar.is-danger .navbar-start > a.navbar-item:focus, .navbar.is-danger .navbar-start > a.navbar-item:hover, .navbar.is-danger .navbar-start > a.navbar-item.is-active,\n  .navbar.is-danger .navbar-start .navbar-link:focus,\n  .navbar.is-danger .navbar-start .navbar-link:hover,\n  .navbar.is-danger .navbar-start .navbar-link.is-active,\n  .navbar.is-danger .navbar-end > a.navbar-item:focus,\n  .navbar.is-danger .navbar-end > a.navbar-item:hover,\n  .navbar.is-danger .navbar-end > a.navbar-item.is-active,\n  .navbar.is-danger .navbar-end .navbar-link:focus,\n  .navbar.is-danger .navbar-end .navbar-link:hover,\n  .navbar.is-danger .navbar-end .navbar-link.is-active {\n    background-color: #ef2e55;\n    color: #fff;\n  }\n  .navbar.is-danger .navbar-start .navbar-link::after,\n  .navbar.is-danger .navbar-end .navbar-link::after {\n    border-color: #fff;\n  }\n  .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,\n  .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,\n  .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #ef2e55;\n    color: #fff;\n  }\n  .navbar.is-danger .navbar-dropdown a.navbar-item.is-active {\n    background-color: #f14668;\n    color: #fff;\n  }\n}\n\n.navbar > .container {\n  align-items: stretch;\n  display: flex;\n  min-height: 3.25rem;\n  width: 100%;\n}\n\n.navbar.has-shadow {\n  box-shadow: 0 2px 0 0 whitesmoke;\n}\n\n.navbar.is-fixed-bottom, .navbar.is-fixed-top {\n  left: 0;\n  position: fixed;\n  right: 0;\n  z-index: 30;\n}\n\n.navbar.is-fixed-bottom {\n  bottom: 0;\n}\n\n.navbar.is-fixed-bottom.has-shadow {\n  box-shadow: 0 -2px 0 0 whitesmoke;\n}\n\n.navbar.is-fixed-top {\n  top: 0;\n}\n\nhtml.has-navbar-fixed-top,\nbody.has-navbar-fixed-top {\n  padding-top: 3.25rem;\n}\n\nhtml.has-navbar-fixed-bottom,\nbody.has-navbar-fixed-bottom {\n  padding-bottom: 3.25rem;\n}\n\n.navbar-brand,\n.navbar-tabs {\n  align-items: stretch;\n  display: flex;\n  flex-shrink: 0;\n  min-height: 3.25rem;\n}\n\n.navbar-brand a.navbar-item:focus, .navbar-brand a.navbar-item:hover {\n  background-color: transparent;\n}\n\n.navbar-tabs {\n  -webkit-overflow-scrolling: touch;\n  max-width: 100vw;\n  overflow-x: auto;\n  overflow-y: hidden;\n}\n\n.navbar-burger {\n  color: #4a4a4a;\n  -moz-appearance: none;\n  -webkit-appearance: none;\n  appearance: none;\n  background: none;\n  border: none;\n  cursor: pointer;\n  display: block;\n  height: 3.25rem;\n  position: relative;\n  width: 3.25rem;\n  margin-left: auto;\n}\n\n.navbar-burger span {\n  background-color: currentColor;\n  display: block;\n  height: 1px;\n  left: calc(50% - 8px);\n  position: absolute;\n  transform-origin: center;\n  transition-duration: 86ms;\n  transition-property: background-color, opacity, transform;\n  transition-timing-function: ease-out;\n  width: 16px;\n}\n\n.navbar-burger span:nth-child(1) {\n  top: calc(50% - 6px);\n}\n\n.navbar-burger span:nth-child(2) {\n  top: calc(50% - 1px);\n}\n\n.navbar-burger span:nth-child(3) {\n  top: calc(50% + 4px);\n}\n\n.navbar-burger:hover {\n  background-color: rgba(0, 0, 0, 0.05);\n}\n\n.navbar-burger.is-active span:nth-child(1) {\n  transform: translateY(5px) rotate(45deg);\n}\n\n.navbar-burger.is-active span:nth-child(2) {\n  opacity: 0;\n}\n\n.navbar-burger.is-active span:nth-child(3) {\n  transform: translateY(-5px) rotate(-45deg);\n}\n\n.navbar-menu {\n  display: none;\n}\n\n.navbar-item,\n.navbar-link {\n  color: #4a4a4a;\n  display: block;\n  line-height: 1.5;\n  padding: 0.5rem 0.75rem;\n  position: relative;\n}\n\n.navbar-item .icon:only-child,\n.navbar-link .icon:only-child {\n  margin-left: -0.25rem;\n  margin-right: -0.25rem;\n}\n\na.navbar-item,\n.navbar-link {\n  cursor: pointer;\n}\n\na.navbar-item:focus, a.navbar-item:focus-within, a.navbar-item:hover, a.navbar-item.is-active,\n.navbar-link:focus,\n.navbar-link:focus-within,\n.navbar-link:hover,\n.navbar-link.is-active {\n  background-color: #fafafa;\n  color: #485fc7;\n}\n\n.navbar-item {\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.navbar-item img {\n  max-height: 1.75rem;\n}\n\n.navbar-item.has-dropdown {\n  padding: 0;\n}\n\n.navbar-item.is-expanded {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.navbar-item.is-tab {\n  border-bottom: 1px solid transparent;\n  min-height: 3.25rem;\n  padding-bottom: calc(0.5rem - 1px);\n}\n\n.navbar-item.is-tab:focus, .navbar-item.is-tab:hover {\n  background-color: transparent;\n  border-bottom-color: #485fc7;\n}\n\n.navbar-item.is-tab.is-active {\n  background-color: transparent;\n  border-bottom-color: #485fc7;\n  border-bottom-style: solid;\n  border-bottom-width: 3px;\n  color: #485fc7;\n  padding-bottom: calc(0.5rem - 3px);\n}\n\n.navbar-content {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.navbar-link:not(.is-arrowless) {\n  padding-right: 2.5em;\n}\n\n.navbar-link:not(.is-arrowless)::after {\n  border-color: #485fc7;\n  margin-top: -0.375em;\n  right: 1.125em;\n}\n\n.navbar-dropdown {\n  font-size: 0.875rem;\n  padding-bottom: 0.5rem;\n  padding-top: 0.5rem;\n}\n\n.navbar-dropdown .navbar-item {\n  padding-left: 1.5rem;\n  padding-right: 1.5rem;\n}\n\n.navbar-divider {\n  background-color: whitesmoke;\n  border: none;\n  display: none;\n  height: 2px;\n  margin: 0.5rem 0;\n}\n\n@media screen and (max-width: 1023px) {\n  .navbar > .container {\n    display: block;\n  }\n  .navbar-brand .navbar-item,\n  .navbar-tabs .navbar-item {\n    align-items: center;\n    display: flex;\n  }\n  .navbar-link::after {\n    display: none;\n  }\n  .navbar-menu {\n    background-color: white;\n    box-shadow: 0 8px 16px rgba(10, 10, 10, 0.1);\n    padding: 0.5rem 0;\n  }\n  .navbar-menu.is-active {\n    display: block;\n  }\n  .navbar.is-fixed-bottom-touch, .navbar.is-fixed-top-touch {\n    left: 0;\n    position: fixed;\n    right: 0;\n    z-index: 30;\n  }\n  .navbar.is-fixed-bottom-touch {\n    bottom: 0;\n  }\n  .navbar.is-fixed-bottom-touch.has-shadow {\n    box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1);\n  }\n  .navbar.is-fixed-top-touch {\n    top: 0;\n  }\n  .navbar.is-fixed-top .navbar-menu, .navbar.is-fixed-top-touch .navbar-menu {\n    -webkit-overflow-scrolling: touch;\n    max-height: calc(100vh - 3.25rem);\n    overflow: auto;\n  }\n  html.has-navbar-fixed-top-touch,\n  body.has-navbar-fixed-top-touch {\n    padding-top: 3.25rem;\n  }\n  html.has-navbar-fixed-bottom-touch,\n  body.has-navbar-fixed-bottom-touch {\n    padding-bottom: 3.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .navbar,\n  .navbar-menu,\n  .navbar-start,\n  .navbar-end {\n    align-items: stretch;\n    display: flex;\n  }\n  .navbar {\n    min-height: 3.25rem;\n  }\n  .navbar.is-spaced {\n    padding: 1rem 2rem;\n  }\n  .navbar.is-spaced .navbar-start,\n  .navbar.is-spaced .navbar-end {\n    align-items: center;\n  }\n  .navbar.is-spaced a.navbar-item,\n  .navbar.is-spaced .navbar-link {\n    border-radius: 4px;\n  }\n  .navbar.is-transparent a.navbar-item:focus, .navbar.is-transparent a.navbar-item:hover, .navbar.is-transparent a.navbar-item.is-active,\n  .navbar.is-transparent .navbar-link:focus,\n  .navbar.is-transparent .navbar-link:hover,\n  .navbar.is-transparent .navbar-link.is-active {\n    background-color: transparent !important;\n  }\n  .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link {\n    background-color: transparent !important;\n  }\n  .navbar.is-transparent .navbar-dropdown a.navbar-item:focus, .navbar.is-transparent .navbar-dropdown a.navbar-item:hover {\n    background-color: whitesmoke;\n    color: #0a0a0a;\n  }\n  .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active {\n    background-color: whitesmoke;\n    color: #485fc7;\n  }\n  .navbar-burger {\n    display: none;\n  }\n  .navbar-item,\n  .navbar-link {\n    align-items: center;\n    display: flex;\n  }\n  .navbar-item.has-dropdown {\n    align-items: stretch;\n  }\n  .navbar-item.has-dropdown-up .navbar-link::after {\n    transform: rotate(135deg) translate(0.25em, -0.25em);\n  }\n  .navbar-item.has-dropdown-up .navbar-dropdown {\n    border-bottom: 2px solid #dbdbdb;\n    border-radius: 6px 6px 0 0;\n    border-top: none;\n    bottom: 100%;\n    box-shadow: 0 -8px 8px rgba(10, 10, 10, 0.1);\n    top: auto;\n  }\n  .navbar-item.is-active .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown {\n    display: block;\n  }\n  .navbar.is-spaced .navbar-item.is-active .navbar-dropdown, .navbar-item.is-active .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed {\n    opacity: 1;\n    pointer-events: auto;\n    transform: translateY(0);\n  }\n  .navbar-menu {\n    flex-grow: 1;\n    flex-shrink: 0;\n  }\n  .navbar-start {\n    justify-content: flex-start;\n    margin-right: auto;\n  }\n  .navbar-end {\n    justify-content: flex-end;\n    margin-left: auto;\n  }\n  .navbar-dropdown {\n    background-color: white;\n    border-bottom-left-radius: 6px;\n    border-bottom-right-radius: 6px;\n    border-top: 2px solid #dbdbdb;\n    box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1);\n    display: none;\n    font-size: 0.875rem;\n    left: 0;\n    min-width: 100%;\n    position: absolute;\n    top: 100%;\n    z-index: 20;\n  }\n  .navbar-dropdown .navbar-item {\n    padding: 0.375rem 1rem;\n    white-space: nowrap;\n  }\n  .navbar-dropdown a.navbar-item {\n    padding-right: 3rem;\n  }\n  .navbar-dropdown a.navbar-item:focus, .navbar-dropdown a.navbar-item:hover {\n    background-color: whitesmoke;\n    color: #0a0a0a;\n  }\n  .navbar-dropdown a.navbar-item.is-active {\n    background-color: whitesmoke;\n    color: #485fc7;\n  }\n  .navbar.is-spaced .navbar-dropdown, .navbar-dropdown.is-boxed {\n    border-radius: 6px;\n    border-top: none;\n    box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1);\n    display: block;\n    opacity: 0;\n    pointer-events: none;\n    top: calc(100% + (-4px));\n    transform: translateY(-5px);\n    transition-duration: 86ms;\n    transition-property: opacity, transform;\n  }\n  .navbar-dropdown.is-right {\n    left: auto;\n    right: 0;\n  }\n  .navbar-divider {\n    display: block;\n  }\n  .navbar > .container .navbar-brand,\n  .container > .navbar .navbar-brand {\n    margin-left: -0.75rem;\n  }\n  .navbar > .container .navbar-menu,\n  .container > .navbar .navbar-menu {\n    margin-right: -0.75rem;\n  }\n  .navbar.is-fixed-bottom-desktop, .navbar.is-fixed-top-desktop {\n    left: 0;\n    position: fixed;\n    right: 0;\n    z-index: 30;\n  }\n  .navbar.is-fixed-bottom-desktop {\n    bottom: 0;\n  }\n  .navbar.is-fixed-bottom-desktop.has-shadow {\n    box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1);\n  }\n  .navbar.is-fixed-top-desktop {\n    top: 0;\n  }\n  html.has-navbar-fixed-top-desktop,\n  body.has-navbar-fixed-top-desktop {\n    padding-top: 3.25rem;\n  }\n  html.has-navbar-fixed-bottom-desktop,\n  body.has-navbar-fixed-bottom-desktop {\n    padding-bottom: 3.25rem;\n  }\n  html.has-spaced-navbar-fixed-top,\n  body.has-spaced-navbar-fixed-top {\n    padding-top: 5.25rem;\n  }\n  html.has-spaced-navbar-fixed-bottom,\n  body.has-spaced-navbar-fixed-bottom {\n    padding-bottom: 5.25rem;\n  }\n  a.navbar-item.is-active,\n  .navbar-link.is-active {\n    color: #0a0a0a;\n  }\n  a.navbar-item.is-active:not(:focus):not(:hover),\n  .navbar-link.is-active:not(:focus):not(:hover) {\n    background-color: transparent;\n  }\n  .navbar-item.has-dropdown:focus .navbar-link, .navbar-item.has-dropdown:hover .navbar-link, .navbar-item.has-dropdown.is-active .navbar-link {\n    background-color: #fafafa;\n  }\n}\n\n.hero.is-fullheight-with-navbar {\n  min-height: calc(100vh - 3.25rem);\n}\n\n.pagination {\n  font-size: 1rem;\n  margin: -0.25rem;\n}\n\n.pagination.is-small {\n  font-size: 0.75rem;\n}\n\n.pagination.is-medium {\n  font-size: 1.25rem;\n}\n\n.pagination.is-large {\n  font-size: 1.5rem;\n}\n\n.pagination.is-rounded .pagination-previous,\n.pagination.is-rounded .pagination-next {\n  padding-left: 1em;\n  padding-right: 1em;\n  border-radius: 9999px;\n}\n\n.pagination.is-rounded .pagination-link {\n  border-radius: 9999px;\n}\n\n.pagination,\n.pagination-list {\n  align-items: center;\n  display: flex;\n  justify-content: center;\n  text-align: center;\n}\n\n.pagination-previous,\n.pagination-next,\n.pagination-link,\n.pagination-ellipsis {\n  font-size: 1em;\n  justify-content: center;\n  margin: 0.25rem;\n  padding-left: 0.5em;\n  padding-right: 0.5em;\n  text-align: center;\n}\n\n.pagination-previous,\n.pagination-next,\n.pagination-link {\n  border-color: #dbdbdb;\n  color: #363636;\n  min-width: 2.5em;\n}\n\n.pagination-previous:hover,\n.pagination-next:hover,\n.pagination-link:hover {\n  border-color: #b5b5b5;\n  color: #363636;\n}\n\n.pagination-previous:focus,\n.pagination-next:focus,\n.pagination-link:focus {\n  border-color: #485fc7;\n}\n\n.pagination-previous:active,\n.pagination-next:active,\n.pagination-link:active {\n  box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2);\n}\n\n.pagination-previous[disabled], .pagination-previous.is-disabled,\n.pagination-next[disabled],\n.pagination-next.is-disabled,\n.pagination-link[disabled],\n.pagination-link.is-disabled {\n  background-color: #dbdbdb;\n  border-color: #dbdbdb;\n  box-shadow: none;\n  color: #7a7a7a;\n  opacity: 0.5;\n}\n\n.pagination-previous,\n.pagination-next {\n  padding-left: 0.75em;\n  padding-right: 0.75em;\n  white-space: nowrap;\n}\n\n.pagination-link.is-current {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n}\n\n.pagination-ellipsis {\n  color: #b5b5b5;\n  pointer-events: none;\n}\n\n.pagination-list {\n  flex-wrap: wrap;\n}\n\n.pagination-list li {\n  list-style: none;\n}\n\n@media screen and (max-width: 768px) {\n  .pagination {\n    flex-wrap: wrap;\n  }\n  .pagination-previous,\n  .pagination-next {\n    flex-grow: 1;\n    flex-shrink: 1;\n  }\n  .pagination-list li {\n    flex-grow: 1;\n    flex-shrink: 1;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .pagination-list {\n    flex-grow: 1;\n    flex-shrink: 1;\n    justify-content: flex-start;\n    order: 1;\n  }\n  .pagination-previous,\n  .pagination-next,\n  .pagination-link,\n  .pagination-ellipsis {\n    margin-bottom: 0;\n    margin-top: 0;\n  }\n  .pagination-previous {\n    order: 2;\n  }\n  .pagination-next {\n    order: 3;\n  }\n  .pagination {\n    justify-content: space-between;\n    margin-bottom: 0;\n    margin-top: 0;\n  }\n  .pagination.is-centered .pagination-previous {\n    order: 1;\n  }\n  .pagination.is-centered .pagination-list {\n    justify-content: center;\n    order: 2;\n  }\n  .pagination.is-centered .pagination-next {\n    order: 3;\n  }\n  .pagination.is-right .pagination-previous {\n    order: 1;\n  }\n  .pagination.is-right .pagination-next {\n    order: 2;\n  }\n  .pagination.is-right .pagination-list {\n    justify-content: flex-end;\n    order: 3;\n  }\n}\n\n.panel {\n  border-radius: 6px;\n  box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02);\n  font-size: 1rem;\n}\n\n.panel:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.panel.is-white .panel-heading {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.panel.is-white .panel-tabs a.is-active {\n  border-bottom-color: white;\n}\n\n.panel.is-white .panel-block.is-active .panel-icon {\n  color: white;\n}\n\n.panel.is-black .panel-heading {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.panel.is-black .panel-tabs a.is-active {\n  border-bottom-color: #0a0a0a;\n}\n\n.panel.is-black .panel-block.is-active .panel-icon {\n  color: #0a0a0a;\n}\n\n.panel.is-light .panel-heading {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.panel.is-light .panel-tabs a.is-active {\n  border-bottom-color: whitesmoke;\n}\n\n.panel.is-light .panel-block.is-active .panel-icon {\n  color: whitesmoke;\n}\n\n.panel.is-dark .panel-heading {\n  background-color: #363636;\n  color: #fff;\n}\n\n.panel.is-dark .panel-tabs a.is-active {\n  border-bottom-color: #363636;\n}\n\n.panel.is-dark .panel-block.is-active .panel-icon {\n  color: #363636;\n}\n\n.panel.is-primary .panel-heading {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.panel.is-primary .panel-tabs a.is-active {\n  border-bottom-color: #00d1b2;\n}\n\n.panel.is-primary .panel-block.is-active .panel-icon {\n  color: #00d1b2;\n}\n\n.panel.is-link .panel-heading {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.panel.is-link .panel-tabs a.is-active {\n  border-bottom-color: #485fc7;\n}\n\n.panel.is-link .panel-block.is-active .panel-icon {\n  color: #485fc7;\n}\n\n.panel.is-info .panel-heading {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.panel.is-info .panel-tabs a.is-active {\n  border-bottom-color: #3e8ed0;\n}\n\n.panel.is-info .panel-block.is-active .panel-icon {\n  color: #3e8ed0;\n}\n\n.panel.is-success .panel-heading {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.panel.is-success .panel-tabs a.is-active {\n  border-bottom-color: #48c78e;\n}\n\n.panel.is-success .panel-block.is-active .panel-icon {\n  color: #48c78e;\n}\n\n.panel.is-warning .panel-heading {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.panel.is-warning .panel-tabs a.is-active {\n  border-bottom-color: #ffe08a;\n}\n\n.panel.is-warning .panel-block.is-active .panel-icon {\n  color: #ffe08a;\n}\n\n.panel.is-danger .panel-heading {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.panel.is-danger .panel-tabs a.is-active {\n  border-bottom-color: #f14668;\n}\n\n.panel.is-danger .panel-block.is-active .panel-icon {\n  color: #f14668;\n}\n\n.panel-tabs:not(:last-child),\n.panel-block:not(:last-child) {\n  border-bottom: 1px solid #ededed;\n}\n\n.panel-heading {\n  background-color: #ededed;\n  border-radius: 6px 6px 0 0;\n  color: #363636;\n  font-size: 1.25em;\n  font-weight: 700;\n  line-height: 1.25;\n  padding: 0.75em 1em;\n}\n\n.panel-tabs {\n  align-items: flex-end;\n  display: flex;\n  font-size: 0.875em;\n  justify-content: center;\n}\n\n.panel-tabs a {\n  border-bottom: 1px solid #dbdbdb;\n  margin-bottom: -1px;\n  padding: 0.5em;\n}\n\n.panel-tabs a.is-active {\n  border-bottom-color: #4a4a4a;\n  color: #363636;\n}\n\n.panel-list a {\n  color: #4a4a4a;\n}\n\n.panel-list a:hover {\n  color: #485fc7;\n}\n\n.panel-block {\n  align-items: center;\n  color: #363636;\n  display: flex;\n  justify-content: flex-start;\n  padding: 0.5em 0.75em;\n}\n\n.panel-block input[type=\"checkbox\"] {\n  margin-right: 0.75em;\n}\n\n.panel-block > .control {\n  flex-grow: 1;\n  flex-shrink: 1;\n  width: 100%;\n}\n\n.panel-block.is-wrapped {\n  flex-wrap: wrap;\n}\n\n.panel-block.is-active {\n  border-left-color: #485fc7;\n  color: #363636;\n}\n\n.panel-block.is-active .panel-icon {\n  color: #485fc7;\n}\n\n.panel-block:last-child {\n  border-bottom-left-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\na.panel-block,\nlabel.panel-block {\n  cursor: pointer;\n}\n\na.panel-block:hover,\nlabel.panel-block:hover {\n  background-color: whitesmoke;\n}\n\n.panel-icon {\n  display: inline-block;\n  font-size: 14px;\n  height: 1em;\n  line-height: 1em;\n  text-align: center;\n  vertical-align: top;\n  width: 1em;\n  color: #7a7a7a;\n  margin-right: 0.75em;\n}\n\n.panel-icon .fa {\n  font-size: inherit;\n  line-height: inherit;\n}\n\n.tabs {\n  -webkit-overflow-scrolling: touch;\n  align-items: stretch;\n  display: flex;\n  font-size: 1rem;\n  justify-content: space-between;\n  overflow: hidden;\n  overflow-x: auto;\n  white-space: nowrap;\n}\n\n.tabs a {\n  align-items: center;\n  border-bottom-color: #dbdbdb;\n  border-bottom-style: solid;\n  border-bottom-width: 1px;\n  color: #4a4a4a;\n  display: flex;\n  justify-content: center;\n  margin-bottom: -1px;\n  padding: 0.5em 1em;\n  vertical-align: top;\n}\n\n.tabs a:hover {\n  border-bottom-color: #363636;\n  color: #363636;\n}\n\n.tabs li {\n  display: block;\n}\n\n.tabs li.is-active a {\n  border-bottom-color: #485fc7;\n  color: #485fc7;\n}\n\n.tabs ul {\n  align-items: center;\n  border-bottom-color: #dbdbdb;\n  border-bottom-style: solid;\n  border-bottom-width: 1px;\n  display: flex;\n  flex-grow: 1;\n  flex-shrink: 0;\n  justify-content: flex-start;\n}\n\n.tabs ul.is-left {\n  padding-right: 0.75em;\n}\n\n.tabs ul.is-center {\n  flex: none;\n  justify-content: center;\n  padding-left: 0.75em;\n  padding-right: 0.75em;\n}\n\n.tabs ul.is-right {\n  justify-content: flex-end;\n  padding-left: 0.75em;\n}\n\n.tabs .icon:first-child {\n  margin-right: 0.5em;\n}\n\n.tabs .icon:last-child {\n  margin-left: 0.5em;\n}\n\n.tabs.is-centered ul {\n  justify-content: center;\n}\n\n.tabs.is-right ul {\n  justify-content: flex-end;\n}\n\n.tabs.is-boxed a {\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n\n.tabs.is-boxed a:hover {\n  background-color: whitesmoke;\n  border-bottom-color: #dbdbdb;\n}\n\n.tabs.is-boxed li.is-active a {\n  background-color: white;\n  border-color: #dbdbdb;\n  border-bottom-color: transparent !important;\n}\n\n.tabs.is-fullwidth li {\n  flex-grow: 1;\n  flex-shrink: 0;\n}\n\n.tabs.is-toggle a {\n  border-color: #dbdbdb;\n  border-style: solid;\n  border-width: 1px;\n  margin-bottom: 0;\n  position: relative;\n}\n\n.tabs.is-toggle a:hover {\n  background-color: whitesmoke;\n  border-color: #b5b5b5;\n  z-index: 2;\n}\n\n.tabs.is-toggle li + li {\n  margin-left: -1px;\n}\n\n.tabs.is-toggle li:first-child a {\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n.tabs.is-toggle li:last-child a {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.tabs.is-toggle li.is-active a {\n  background-color: #485fc7;\n  border-color: #485fc7;\n  color: #fff;\n  z-index: 1;\n}\n\n.tabs.is-toggle ul {\n  border-bottom: none;\n}\n\n.tabs.is-toggle.is-toggle-rounded li:first-child a {\n  border-bottom-left-radius: 9999px;\n  border-top-left-radius: 9999px;\n  padding-left: 1.25em;\n}\n\n.tabs.is-toggle.is-toggle-rounded li:last-child a {\n  border-bottom-right-radius: 9999px;\n  border-top-right-radius: 9999px;\n  padding-right: 1.25em;\n}\n\n.tabs.is-small {\n  font-size: 0.75rem;\n}\n\n.tabs.is-medium {\n  font-size: 1.25rem;\n}\n\n.tabs.is-large {\n  font-size: 1.5rem;\n}\n\n/* Bulma Grid */\n.column {\n  display: block;\n  flex-basis: 0;\n  flex-grow: 1;\n  flex-shrink: 1;\n  padding: 0.75rem;\n}\n\n.columns.is-mobile > .column.is-narrow {\n  flex: none;\n  width: unset;\n}\n\n.columns.is-mobile > .column.is-full {\n  flex: none;\n  width: 100%;\n}\n\n.columns.is-mobile > .column.is-three-quarters {\n  flex: none;\n  width: 75%;\n}\n\n.columns.is-mobile > .column.is-two-thirds {\n  flex: none;\n  width: 66.6666%;\n}\n\n.columns.is-mobile > .column.is-half {\n  flex: none;\n  width: 50%;\n}\n\n.columns.is-mobile > .column.is-one-third {\n  flex: none;\n  width: 33.3333%;\n}\n\n.columns.is-mobile > .column.is-one-quarter {\n  flex: none;\n  width: 25%;\n}\n\n.columns.is-mobile > .column.is-one-fifth {\n  flex: none;\n  width: 20%;\n}\n\n.columns.is-mobile > .column.is-two-fifths {\n  flex: none;\n  width: 40%;\n}\n\n.columns.is-mobile > .column.is-three-fifths {\n  flex: none;\n  width: 60%;\n}\n\n.columns.is-mobile > .column.is-four-fifths {\n  flex: none;\n  width: 80%;\n}\n\n.columns.is-mobile > .column.is-offset-three-quarters {\n  margin-left: 75%;\n}\n\n.columns.is-mobile > .column.is-offset-two-thirds {\n  margin-left: 66.6666%;\n}\n\n.columns.is-mobile > .column.is-offset-half {\n  margin-left: 50%;\n}\n\n.columns.is-mobile > .column.is-offset-one-third {\n  margin-left: 33.3333%;\n}\n\n.columns.is-mobile > .column.is-offset-one-quarter {\n  margin-left: 25%;\n}\n\n.columns.is-mobile > .column.is-offset-one-fifth {\n  margin-left: 20%;\n}\n\n.columns.is-mobile > .column.is-offset-two-fifths {\n  margin-left: 40%;\n}\n\n.columns.is-mobile > .column.is-offset-three-fifths {\n  margin-left: 60%;\n}\n\n.columns.is-mobile > .column.is-offset-four-fifths {\n  margin-left: 80%;\n}\n\n.columns.is-mobile > .column.is-0 {\n  flex: none;\n  width: 0%;\n}\n\n.columns.is-mobile > .column.is-offset-0 {\n  margin-left: 0%;\n}\n\n.columns.is-mobile > .column.is-1 {\n  flex: none;\n  width: 8.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-1 {\n  margin-left: 8.33333%;\n}\n\n.columns.is-mobile > .column.is-2 {\n  flex: none;\n  width: 16.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-2 {\n  margin-left: 16.66667%;\n}\n\n.columns.is-mobile > .column.is-3 {\n  flex: none;\n  width: 25%;\n}\n\n.columns.is-mobile > .column.is-offset-3 {\n  margin-left: 25%;\n}\n\n.columns.is-mobile > .column.is-4 {\n  flex: none;\n  width: 33.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-4 {\n  margin-left: 33.33333%;\n}\n\n.columns.is-mobile > .column.is-5 {\n  flex: none;\n  width: 41.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-5 {\n  margin-left: 41.66667%;\n}\n\n.columns.is-mobile > .column.is-6 {\n  flex: none;\n  width: 50%;\n}\n\n.columns.is-mobile > .column.is-offset-6 {\n  margin-left: 50%;\n}\n\n.columns.is-mobile > .column.is-7 {\n  flex: none;\n  width: 58.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-7 {\n  margin-left: 58.33333%;\n}\n\n.columns.is-mobile > .column.is-8 {\n  flex: none;\n  width: 66.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-8 {\n  margin-left: 66.66667%;\n}\n\n.columns.is-mobile > .column.is-9 {\n  flex: none;\n  width: 75%;\n}\n\n.columns.is-mobile > .column.is-offset-9 {\n  margin-left: 75%;\n}\n\n.columns.is-mobile > .column.is-10 {\n  flex: none;\n  width: 83.33333%;\n}\n\n.columns.is-mobile > .column.is-offset-10 {\n  margin-left: 83.33333%;\n}\n\n.columns.is-mobile > .column.is-11 {\n  flex: none;\n  width: 91.66667%;\n}\n\n.columns.is-mobile > .column.is-offset-11 {\n  margin-left: 91.66667%;\n}\n\n.columns.is-mobile > .column.is-12 {\n  flex: none;\n  width: 100%;\n}\n\n.columns.is-mobile > .column.is-offset-12 {\n  margin-left: 100%;\n}\n\n@media screen and (max-width: 768px) {\n  .column.is-narrow-mobile {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-mobile {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-mobile {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-mobile {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-mobile {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-mobile {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-mobile {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-mobile {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-mobile {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-mobile {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-mobile {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-mobile {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-mobile {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-mobile {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-mobile {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-mobile {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-mobile {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-mobile {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-mobile {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-mobile {\n    margin-left: 80%;\n  }\n  .column.is-0-mobile {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-mobile {\n    margin-left: 0%;\n  }\n  .column.is-1-mobile {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-mobile {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-mobile {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-mobile {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-mobile {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-mobile {\n    margin-left: 25%;\n  }\n  .column.is-4-mobile {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-mobile {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-mobile {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-mobile {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-mobile {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-mobile {\n    margin-left: 50%;\n  }\n  .column.is-7-mobile {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-mobile {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-mobile {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-mobile {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-mobile {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-mobile {\n    margin-left: 75%;\n  }\n  .column.is-10-mobile {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-mobile {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-mobile {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-mobile {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-mobile {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-mobile {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .column.is-narrow, .column.is-narrow-tablet {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full, .column.is-full-tablet {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters, .column.is-three-quarters-tablet {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds, .column.is-two-thirds-tablet {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half, .column.is-half-tablet {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third, .column.is-one-third-tablet {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter, .column.is-one-quarter-tablet {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth, .column.is-one-fifth-tablet {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths, .column.is-two-fifths-tablet {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths, .column.is-three-fifths-tablet {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths, .column.is-four-fifths-tablet {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters, .column.is-offset-three-quarters-tablet {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds, .column.is-offset-two-thirds-tablet {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half, .column.is-offset-half-tablet {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third, .column.is-offset-one-third-tablet {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter, .column.is-offset-one-quarter-tablet {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth, .column.is-offset-one-fifth-tablet {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths, .column.is-offset-two-fifths-tablet {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths, .column.is-offset-three-fifths-tablet {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths, .column.is-offset-four-fifths-tablet {\n    margin-left: 80%;\n  }\n  .column.is-0, .column.is-0-tablet {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0, .column.is-offset-0-tablet {\n    margin-left: 0%;\n  }\n  .column.is-1, .column.is-1-tablet {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1, .column.is-offset-1-tablet {\n    margin-left: 8.33333%;\n  }\n  .column.is-2, .column.is-2-tablet {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2, .column.is-offset-2-tablet {\n    margin-left: 16.66667%;\n  }\n  .column.is-3, .column.is-3-tablet {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3, .column.is-offset-3-tablet {\n    margin-left: 25%;\n  }\n  .column.is-4, .column.is-4-tablet {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4, .column.is-offset-4-tablet {\n    margin-left: 33.33333%;\n  }\n  .column.is-5, .column.is-5-tablet {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5, .column.is-offset-5-tablet {\n    margin-left: 41.66667%;\n  }\n  .column.is-6, .column.is-6-tablet {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6, .column.is-offset-6-tablet {\n    margin-left: 50%;\n  }\n  .column.is-7, .column.is-7-tablet {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7, .column.is-offset-7-tablet {\n    margin-left: 58.33333%;\n  }\n  .column.is-8, .column.is-8-tablet {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8, .column.is-offset-8-tablet {\n    margin-left: 66.66667%;\n  }\n  .column.is-9, .column.is-9-tablet {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9, .column.is-offset-9-tablet {\n    margin-left: 75%;\n  }\n  .column.is-10, .column.is-10-tablet {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10, .column.is-offset-10-tablet {\n    margin-left: 83.33333%;\n  }\n  .column.is-11, .column.is-11-tablet {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11, .column.is-offset-11-tablet {\n    margin-left: 91.66667%;\n  }\n  .column.is-12, .column.is-12-tablet {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12, .column.is-offset-12-tablet {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .column.is-narrow-touch {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-touch {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-touch {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-touch {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-touch {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-touch {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-touch {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-touch {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-touch {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-touch {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-touch {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-touch {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-touch {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-touch {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-touch {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-touch {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-touch {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-touch {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-touch {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-touch {\n    margin-left: 80%;\n  }\n  .column.is-0-touch {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-touch {\n    margin-left: 0%;\n  }\n  .column.is-1-touch {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-touch {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-touch {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-touch {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-touch {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-touch {\n    margin-left: 25%;\n  }\n  .column.is-4-touch {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-touch {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-touch {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-touch {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-touch {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-touch {\n    margin-left: 50%;\n  }\n  .column.is-7-touch {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-touch {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-touch {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-touch {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-touch {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-touch {\n    margin-left: 75%;\n  }\n  .column.is-10-touch {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-touch {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-touch {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-touch {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-touch {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-touch {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .column.is-narrow-desktop {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-desktop {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-desktop {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-desktop {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-desktop {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-desktop {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-desktop {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-desktop {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-desktop {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-desktop {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-desktop {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-desktop {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-desktop {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-desktop {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-desktop {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-desktop {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-desktop {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-desktop {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-desktop {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-desktop {\n    margin-left: 80%;\n  }\n  .column.is-0-desktop {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-desktop {\n    margin-left: 0%;\n  }\n  .column.is-1-desktop {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-desktop {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-desktop {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-desktop {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-desktop {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-desktop {\n    margin-left: 25%;\n  }\n  .column.is-4-desktop {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-desktop {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-desktop {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-desktop {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-desktop {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-desktop {\n    margin-left: 50%;\n  }\n  .column.is-7-desktop {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-desktop {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-desktop {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-desktop {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-desktop {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-desktop {\n    margin-left: 75%;\n  }\n  .column.is-10-desktop {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-desktop {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-desktop {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-desktop {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-desktop {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-desktop {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .column.is-narrow-widescreen {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-widescreen {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-widescreen {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-widescreen {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-widescreen {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-widescreen {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-widescreen {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-widescreen {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-widescreen {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-widescreen {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-widescreen {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-widescreen {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-widescreen {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-widescreen {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-widescreen {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-widescreen {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-widescreen {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-widescreen {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-widescreen {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-widescreen {\n    margin-left: 80%;\n  }\n  .column.is-0-widescreen {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-widescreen {\n    margin-left: 0%;\n  }\n  .column.is-1-widescreen {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-widescreen {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-widescreen {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-widescreen {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-widescreen {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-widescreen {\n    margin-left: 25%;\n  }\n  .column.is-4-widescreen {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-widescreen {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-widescreen {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-widescreen {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-widescreen {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-widescreen {\n    margin-left: 50%;\n  }\n  .column.is-7-widescreen {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-widescreen {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-widescreen {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-widescreen {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-widescreen {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-widescreen {\n    margin-left: 75%;\n  }\n  .column.is-10-widescreen {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-widescreen {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-widescreen {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-widescreen {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-widescreen {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-widescreen {\n    margin-left: 100%;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .column.is-narrow-fullhd {\n    flex: none;\n    width: unset;\n  }\n  .column.is-full-fullhd {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-three-quarters-fullhd {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-two-thirds-fullhd {\n    flex: none;\n    width: 66.6666%;\n  }\n  .column.is-half-fullhd {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-one-third-fullhd {\n    flex: none;\n    width: 33.3333%;\n  }\n  .column.is-one-quarter-fullhd {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-one-fifth-fullhd {\n    flex: none;\n    width: 20%;\n  }\n  .column.is-two-fifths-fullhd {\n    flex: none;\n    width: 40%;\n  }\n  .column.is-three-fifths-fullhd {\n    flex: none;\n    width: 60%;\n  }\n  .column.is-four-fifths-fullhd {\n    flex: none;\n    width: 80%;\n  }\n  .column.is-offset-three-quarters-fullhd {\n    margin-left: 75%;\n  }\n  .column.is-offset-two-thirds-fullhd {\n    margin-left: 66.6666%;\n  }\n  .column.is-offset-half-fullhd {\n    margin-left: 50%;\n  }\n  .column.is-offset-one-third-fullhd {\n    margin-left: 33.3333%;\n  }\n  .column.is-offset-one-quarter-fullhd {\n    margin-left: 25%;\n  }\n  .column.is-offset-one-fifth-fullhd {\n    margin-left: 20%;\n  }\n  .column.is-offset-two-fifths-fullhd {\n    margin-left: 40%;\n  }\n  .column.is-offset-three-fifths-fullhd {\n    margin-left: 60%;\n  }\n  .column.is-offset-four-fifths-fullhd {\n    margin-left: 80%;\n  }\n  .column.is-0-fullhd {\n    flex: none;\n    width: 0%;\n  }\n  .column.is-offset-0-fullhd {\n    margin-left: 0%;\n  }\n  .column.is-1-fullhd {\n    flex: none;\n    width: 8.33333%;\n  }\n  .column.is-offset-1-fullhd {\n    margin-left: 8.33333%;\n  }\n  .column.is-2-fullhd {\n    flex: none;\n    width: 16.66667%;\n  }\n  .column.is-offset-2-fullhd {\n    margin-left: 16.66667%;\n  }\n  .column.is-3-fullhd {\n    flex: none;\n    width: 25%;\n  }\n  .column.is-offset-3-fullhd {\n    margin-left: 25%;\n  }\n  .column.is-4-fullhd {\n    flex: none;\n    width: 33.33333%;\n  }\n  .column.is-offset-4-fullhd {\n    margin-left: 33.33333%;\n  }\n  .column.is-5-fullhd {\n    flex: none;\n    width: 41.66667%;\n  }\n  .column.is-offset-5-fullhd {\n    margin-left: 41.66667%;\n  }\n  .column.is-6-fullhd {\n    flex: none;\n    width: 50%;\n  }\n  .column.is-offset-6-fullhd {\n    margin-left: 50%;\n  }\n  .column.is-7-fullhd {\n    flex: none;\n    width: 58.33333%;\n  }\n  .column.is-offset-7-fullhd {\n    margin-left: 58.33333%;\n  }\n  .column.is-8-fullhd {\n    flex: none;\n    width: 66.66667%;\n  }\n  .column.is-offset-8-fullhd {\n    margin-left: 66.66667%;\n  }\n  .column.is-9-fullhd {\n    flex: none;\n    width: 75%;\n  }\n  .column.is-offset-9-fullhd {\n    margin-left: 75%;\n  }\n  .column.is-10-fullhd {\n    flex: none;\n    width: 83.33333%;\n  }\n  .column.is-offset-10-fullhd {\n    margin-left: 83.33333%;\n  }\n  .column.is-11-fullhd {\n    flex: none;\n    width: 91.66667%;\n  }\n  .column.is-offset-11-fullhd {\n    margin-left: 91.66667%;\n  }\n  .column.is-12-fullhd {\n    flex: none;\n    width: 100%;\n  }\n  .column.is-offset-12-fullhd {\n    margin-left: 100%;\n  }\n}\n\n.columns {\n  margin-left: -0.75rem;\n  margin-right: -0.75rem;\n  margin-top: -0.75rem;\n}\n\n.columns:last-child {\n  margin-bottom: -0.75rem;\n}\n\n.columns:not(:last-child) {\n  margin-bottom: calc(1.5rem - 0.75rem);\n}\n\n.columns.is-centered {\n  justify-content: center;\n}\n\n.columns.is-gapless {\n  margin-left: 0;\n  margin-right: 0;\n  margin-top: 0;\n}\n\n.columns.is-gapless > .column {\n  margin: 0;\n  padding: 0 !important;\n}\n\n.columns.is-gapless:not(:last-child) {\n  margin-bottom: 1.5rem;\n}\n\n.columns.is-gapless:last-child {\n  margin-bottom: 0;\n}\n\n.columns.is-mobile {\n  display: flex;\n}\n\n.columns.is-multiline {\n  flex-wrap: wrap;\n}\n\n.columns.is-vcentered {\n  align-items: center;\n}\n\n@media screen and (min-width: 769px), print {\n  .columns:not(.is-desktop) {\n    display: flex;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-desktop {\n    display: flex;\n  }\n}\n\n.columns.is-variable {\n  --columnGap: 0.75rem;\n  margin-left: calc(-1 * var(--columnGap));\n  margin-right: calc(-1 * var(--columnGap));\n}\n\n.columns.is-variable > .column {\n  padding-left: var(--columnGap);\n  padding-right: var(--columnGap);\n}\n\n.columns.is-variable.is-0 {\n  --columnGap: 0rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-0-mobile {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-0-tablet {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-0-tablet-only {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-0-touch {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-0-desktop {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-0-desktop-only {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-0-widescreen {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-0-widescreen-only {\n    --columnGap: 0rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-0-fullhd {\n    --columnGap: 0rem;\n  }\n}\n\n.columns.is-variable.is-1 {\n  --columnGap: 0.25rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-1-mobile {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-1-tablet {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-1-tablet-only {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-1-touch {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-1-desktop {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-1-desktop-only {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-1-widescreen {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-1-widescreen-only {\n    --columnGap: 0.25rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-1-fullhd {\n    --columnGap: 0.25rem;\n  }\n}\n\n.columns.is-variable.is-2 {\n  --columnGap: 0.5rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-2-mobile {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-2-tablet {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-2-tablet-only {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-2-touch {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-2-desktop {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-2-desktop-only {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-2-widescreen {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-2-widescreen-only {\n    --columnGap: 0.5rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-2-fullhd {\n    --columnGap: 0.5rem;\n  }\n}\n\n.columns.is-variable.is-3 {\n  --columnGap: 0.75rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-3-mobile {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-3-tablet {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-3-tablet-only {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-3-touch {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-3-desktop {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-3-desktop-only {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-3-widescreen {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-3-widescreen-only {\n    --columnGap: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-3-fullhd {\n    --columnGap: 0.75rem;\n  }\n}\n\n.columns.is-variable.is-4 {\n  --columnGap: 1rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-4-mobile {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-4-tablet {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-4-tablet-only {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-4-touch {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-4-desktop {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-4-desktop-only {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-4-widescreen {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-4-widescreen-only {\n    --columnGap: 1rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-4-fullhd {\n    --columnGap: 1rem;\n  }\n}\n\n.columns.is-variable.is-5 {\n  --columnGap: 1.25rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-5-mobile {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-5-tablet {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-5-tablet-only {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-5-touch {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-5-desktop {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-5-desktop-only {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-5-widescreen {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-5-widescreen-only {\n    --columnGap: 1.25rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-5-fullhd {\n    --columnGap: 1.25rem;\n  }\n}\n\n.columns.is-variable.is-6 {\n  --columnGap: 1.5rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-6-mobile {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-6-tablet {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-6-tablet-only {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-6-touch {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-6-desktop {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-6-desktop-only {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-6-widescreen {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-6-widescreen-only {\n    --columnGap: 1.5rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-6-fullhd {\n    --columnGap: 1.5rem;\n  }\n}\n\n.columns.is-variable.is-7 {\n  --columnGap: 1.75rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-7-mobile {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-7-tablet {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-7-tablet-only {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-7-touch {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-7-desktop {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-7-desktop-only {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-7-widescreen {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-7-widescreen-only {\n    --columnGap: 1.75rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-7-fullhd {\n    --columnGap: 1.75rem;\n  }\n}\n\n.columns.is-variable.is-8 {\n  --columnGap: 2rem;\n}\n\n@media screen and (max-width: 768px) {\n  .columns.is-variable.is-8-mobile {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .columns.is-variable.is-8-tablet {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .columns.is-variable.is-8-tablet-only {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .columns.is-variable.is-8-touch {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .columns.is-variable.is-8-desktop {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .columns.is-variable.is-8-desktop-only {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .columns.is-variable.is-8-widescreen {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .columns.is-variable.is-8-widescreen-only {\n    --columnGap: 2rem;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .columns.is-variable.is-8-fullhd {\n    --columnGap: 2rem;\n  }\n}\n\n.tile {\n  align-items: stretch;\n  display: block;\n  flex-basis: 0;\n  flex-grow: 1;\n  flex-shrink: 1;\n  min-height: -webkit-min-content;\n  min-height: -moz-min-content;\n  min-height: min-content;\n}\n\n.tile.is-ancestor {\n  margin-left: -0.75rem;\n  margin-right: -0.75rem;\n  margin-top: -0.75rem;\n}\n\n.tile.is-ancestor:last-child {\n  margin-bottom: -0.75rem;\n}\n\n.tile.is-ancestor:not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.tile.is-child {\n  margin: 0 !important;\n}\n\n.tile.is-parent {\n  padding: 0.75rem;\n}\n\n.tile.is-vertical {\n  flex-direction: column;\n}\n\n.tile.is-vertical > .tile.is-child:not(:last-child) {\n  margin-bottom: 1.5rem !important;\n}\n\n@media screen and (min-width: 769px), print {\n  .tile:not(.is-child) {\n    display: flex;\n  }\n  .tile.is-1 {\n    flex: none;\n    width: 8.33333%;\n  }\n  .tile.is-2 {\n    flex: none;\n    width: 16.66667%;\n  }\n  .tile.is-3 {\n    flex: none;\n    width: 25%;\n  }\n  .tile.is-4 {\n    flex: none;\n    width: 33.33333%;\n  }\n  .tile.is-5 {\n    flex: none;\n    width: 41.66667%;\n  }\n  .tile.is-6 {\n    flex: none;\n    width: 50%;\n  }\n  .tile.is-7 {\n    flex: none;\n    width: 58.33333%;\n  }\n  .tile.is-8 {\n    flex: none;\n    width: 66.66667%;\n  }\n  .tile.is-9 {\n    flex: none;\n    width: 75%;\n  }\n  .tile.is-10 {\n    flex: none;\n    width: 83.33333%;\n  }\n  .tile.is-11 {\n    flex: none;\n    width: 91.66667%;\n  }\n  .tile.is-12 {\n    flex: none;\n    width: 100%;\n  }\n}\n\n/* Bulma Helpers */\n.has-text-white {\n  color: white !important;\n}\n\na.has-text-white:hover, a.has-text-white:focus {\n  color: #e6e6e6 !important;\n}\n\n.has-background-white {\n  background-color: white !important;\n}\n\n.has-text-black {\n  color: #0a0a0a !important;\n}\n\na.has-text-black:hover, a.has-text-black:focus {\n  color: black !important;\n}\n\n.has-background-black {\n  background-color: #0a0a0a !important;\n}\n\n.has-text-light {\n  color: whitesmoke !important;\n}\n\na.has-text-light:hover, a.has-text-light:focus {\n  color: #dbdbdb !important;\n}\n\n.has-background-light {\n  background-color: whitesmoke !important;\n}\n\n.has-text-dark {\n  color: #363636 !important;\n}\n\na.has-text-dark:hover, a.has-text-dark:focus {\n  color: #1c1c1c !important;\n}\n\n.has-background-dark {\n  background-color: #363636 !important;\n}\n\n.has-text-primary {\n  color: #00d1b2 !important;\n}\n\na.has-text-primary:hover, a.has-text-primary:focus {\n  color: #009e86 !important;\n}\n\n.has-background-primary {\n  background-color: #00d1b2 !important;\n}\n\n.has-text-primary-light {\n  color: #ebfffc !important;\n}\n\na.has-text-primary-light:hover, a.has-text-primary-light:focus {\n  color: #b8fff4 !important;\n}\n\n.has-background-primary-light {\n  background-color: #ebfffc !important;\n}\n\n.has-text-primary-dark {\n  color: #00947e !important;\n}\n\na.has-text-primary-dark:hover, a.has-text-primary-dark:focus {\n  color: #00c7a9 !important;\n}\n\n.has-background-primary-dark {\n  background-color: #00947e !important;\n}\n\n.has-text-link {\n  color: #485fc7 !important;\n}\n\na.has-text-link:hover, a.has-text-link:focus {\n  color: #3449a8 !important;\n}\n\n.has-background-link {\n  background-color: #485fc7 !important;\n}\n\n.has-text-link-light {\n  color: #eff1fa !important;\n}\n\na.has-text-link-light:hover, a.has-text-link-light:focus {\n  color: #c8cfee !important;\n}\n\n.has-background-link-light {\n  background-color: #eff1fa !important;\n}\n\n.has-text-link-dark {\n  color: #3850b7 !important;\n}\n\na.has-text-link-dark:hover, a.has-text-link-dark:focus {\n  color: #576dcb !important;\n}\n\n.has-background-link-dark {\n  background-color: #3850b7 !important;\n}\n\n.has-text-info {\n  color: #3e8ed0 !important;\n}\n\na.has-text-info:hover, a.has-text-info:focus {\n  color: #2b74b1 !important;\n}\n\n.has-background-info {\n  background-color: #3e8ed0 !important;\n}\n\n.has-text-info-light {\n  color: #eff5fb !important;\n}\n\na.has-text-info-light:hover, a.has-text-info-light:focus {\n  color: #c6ddf1 !important;\n}\n\n.has-background-info-light {\n  background-color: #eff5fb !important;\n}\n\n.has-text-info-dark {\n  color: #296fa8 !important;\n}\n\na.has-text-info-dark:hover, a.has-text-info-dark:focus {\n  color: #368ace !important;\n}\n\n.has-background-info-dark {\n  background-color: #296fa8 !important;\n}\n\n.has-text-success {\n  color: #48c78e !important;\n}\n\na.has-text-success:hover, a.has-text-success:focus {\n  color: #34a873 !important;\n}\n\n.has-background-success {\n  background-color: #48c78e !important;\n}\n\n.has-text-success-light {\n  color: #effaf5 !important;\n}\n\na.has-text-success-light:hover, a.has-text-success-light:focus {\n  color: #c8eedd !important;\n}\n\n.has-background-success-light {\n  background-color: #effaf5 !important;\n}\n\n.has-text-success-dark {\n  color: #257953 !important;\n}\n\na.has-text-success-dark:hover, a.has-text-success-dark:focus {\n  color: #31a06e !important;\n}\n\n.has-background-success-dark {\n  background-color: #257953 !important;\n}\n\n.has-text-warning {\n  color: #ffe08a !important;\n}\n\na.has-text-warning:hover, a.has-text-warning:focus {\n  color: #ffd257 !important;\n}\n\n.has-background-warning {\n  background-color: #ffe08a !important;\n}\n\n.has-text-warning-light {\n  color: #fffaeb !important;\n}\n\na.has-text-warning-light:hover, a.has-text-warning-light:focus {\n  color: #ffecb8 !important;\n}\n\n.has-background-warning-light {\n  background-color: #fffaeb !important;\n}\n\n.has-text-warning-dark {\n  color: #946c00 !important;\n}\n\na.has-text-warning-dark:hover, a.has-text-warning-dark:focus {\n  color: #c79200 !important;\n}\n\n.has-background-warning-dark {\n  background-color: #946c00 !important;\n}\n\n.has-text-danger {\n  color: #f14668 !important;\n}\n\na.has-text-danger:hover, a.has-text-danger:focus {\n  color: #ee1742 !important;\n}\n\n.has-background-danger {\n  background-color: #f14668 !important;\n}\n\n.has-text-danger-light {\n  color: #feecf0 !important;\n}\n\na.has-text-danger-light:hover, a.has-text-danger-light:focus {\n  color: #fabdc9 !important;\n}\n\n.has-background-danger-light {\n  background-color: #feecf0 !important;\n}\n\n.has-text-danger-dark {\n  color: #cc0f35 !important;\n}\n\na.has-text-danger-dark:hover, a.has-text-danger-dark:focus {\n  color: #ee2049 !important;\n}\n\n.has-background-danger-dark {\n  background-color: #cc0f35 !important;\n}\n\n.has-text-black-bis {\n  color: #121212 !important;\n}\n\n.has-background-black-bis {\n  background-color: #121212 !important;\n}\n\n.has-text-black-ter {\n  color: #242424 !important;\n}\n\n.has-background-black-ter {\n  background-color: #242424 !important;\n}\n\n.has-text-grey-darker {\n  color: #363636 !important;\n}\n\n.has-background-grey-darker {\n  background-color: #363636 !important;\n}\n\n.has-text-grey-dark {\n  color: #4a4a4a !important;\n}\n\n.has-background-grey-dark {\n  background-color: #4a4a4a !important;\n}\n\n.has-text-grey {\n  color: #7a7a7a !important;\n}\n\n.has-background-grey {\n  background-color: #7a7a7a !important;\n}\n\n.has-text-grey-light {\n  color: #b5b5b5 !important;\n}\n\n.has-background-grey-light {\n  background-color: #b5b5b5 !important;\n}\n\n.has-text-grey-lighter {\n  color: #dbdbdb !important;\n}\n\n.has-background-grey-lighter {\n  background-color: #dbdbdb !important;\n}\n\n.has-text-white-ter {\n  color: whitesmoke !important;\n}\n\n.has-background-white-ter {\n  background-color: whitesmoke !important;\n}\n\n.has-text-white-bis {\n  color: #fafafa !important;\n}\n\n.has-background-white-bis {\n  background-color: #fafafa !important;\n}\n\n.is-flex-direction-row {\n  flex-direction: row !important;\n}\n\n.is-flex-direction-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.is-flex-direction-column {\n  flex-direction: column !important;\n}\n\n.is-flex-direction-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.is-flex-wrap-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.is-flex-wrap-wrap {\n  flex-wrap: wrap !important;\n}\n\n.is-flex-wrap-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.is-justify-content-flex-start {\n  justify-content: flex-start !important;\n}\n\n.is-justify-content-flex-end {\n  justify-content: flex-end !important;\n}\n\n.is-justify-content-center {\n  justify-content: center !important;\n}\n\n.is-justify-content-space-between {\n  justify-content: space-between !important;\n}\n\n.is-justify-content-space-around {\n  justify-content: space-around !important;\n}\n\n.is-justify-content-space-evenly {\n  justify-content: space-evenly !important;\n}\n\n.is-justify-content-start {\n  justify-content: start !important;\n}\n\n.is-justify-content-end {\n  justify-content: end !important;\n}\n\n.is-justify-content-left {\n  justify-content: left !important;\n}\n\n.is-justify-content-right {\n  justify-content: right !important;\n}\n\n.is-align-content-flex-start {\n  align-content: flex-start !important;\n}\n\n.is-align-content-flex-end {\n  align-content: flex-end !important;\n}\n\n.is-align-content-center {\n  align-content: center !important;\n}\n\n.is-align-content-space-between {\n  align-content: space-between !important;\n}\n\n.is-align-content-space-around {\n  align-content: space-around !important;\n}\n\n.is-align-content-space-evenly {\n  align-content: space-evenly !important;\n}\n\n.is-align-content-stretch {\n  align-content: stretch !important;\n}\n\n.is-align-content-start {\n  align-content: start !important;\n}\n\n.is-align-content-end {\n  align-content: end !important;\n}\n\n.is-align-content-baseline {\n  align-content: baseline !important;\n}\n\n.is-align-items-stretch {\n  align-items: stretch !important;\n}\n\n.is-align-items-flex-start {\n  align-items: flex-start !important;\n}\n\n.is-align-items-flex-end {\n  align-items: flex-end !important;\n}\n\n.is-align-items-center {\n  align-items: center !important;\n}\n\n.is-align-items-baseline {\n  align-items: baseline !important;\n}\n\n.is-align-items-start {\n  align-items: start !important;\n}\n\n.is-align-items-end {\n  align-items: end !important;\n}\n\n.is-align-items-self-start {\n  align-items: self-start !important;\n}\n\n.is-align-items-self-end {\n  align-items: self-end !important;\n}\n\n.is-align-self-auto {\n  align-self: auto !important;\n}\n\n.is-align-self-flex-start {\n  align-self: flex-start !important;\n}\n\n.is-align-self-flex-end {\n  align-self: flex-end !important;\n}\n\n.is-align-self-center {\n  align-self: center !important;\n}\n\n.is-align-self-baseline {\n  align-self: baseline !important;\n}\n\n.is-align-self-stretch {\n  align-self: stretch !important;\n}\n\n.is-flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.is-flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.is-flex-grow-2 {\n  flex-grow: 2 !important;\n}\n\n.is-flex-grow-3 {\n  flex-grow: 3 !important;\n}\n\n.is-flex-grow-4 {\n  flex-grow: 4 !important;\n}\n\n.is-flex-grow-5 {\n  flex-grow: 5 !important;\n}\n\n.is-flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.is-flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.is-flex-shrink-2 {\n  flex-shrink: 2 !important;\n}\n\n.is-flex-shrink-3 {\n  flex-shrink: 3 !important;\n}\n\n.is-flex-shrink-4 {\n  flex-shrink: 4 !important;\n}\n\n.is-flex-shrink-5 {\n  flex-shrink: 5 !important;\n}\n\n.is-clearfix::after {\n  clear: both;\n  content: \" \";\n  display: table;\n}\n\n.is-pulled-left {\n  float: left !important;\n}\n\n.is-pulled-right {\n  float: right !important;\n}\n\n.is-radiusless {\n  border-radius: 0 !important;\n}\n\n.is-shadowless {\n  box-shadow: none !important;\n}\n\n.is-clickable {\n  cursor: pointer !important;\n  pointer-events: all !important;\n}\n\n.is-clipped {\n  overflow: hidden !important;\n}\n\n.is-relative {\n  position: relative !important;\n}\n\n.is-marginless {\n  margin: 0 !important;\n}\n\n.is-paddingless {\n  padding: 0 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mr-0 {\n  margin-right: 0 !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.ml-0 {\n  margin-left: 0 !important;\n}\n\n.mx-0 {\n  margin-left: 0 !important;\n  margin-right: 0 !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mr-1 {\n  margin-right: 0.25rem !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.ml-1 {\n  margin-left: 0.25rem !important;\n}\n\n.mx-1 {\n  margin-left: 0.25rem !important;\n  margin-right: 0.25rem !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mr-2 {\n  margin-right: 0.5rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.ml-2 {\n  margin-left: 0.5rem !important;\n}\n\n.mx-2 {\n  margin-left: 0.5rem !important;\n  margin-right: 0.5rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 0.75rem !important;\n}\n\n.mt-3 {\n  margin-top: 0.75rem !important;\n}\n\n.mr-3 {\n  margin-right: 0.75rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 0.75rem !important;\n}\n\n.ml-3 {\n  margin-left: 0.75rem !important;\n}\n\n.mx-3 {\n  margin-left: 0.75rem !important;\n  margin-right: 0.75rem !important;\n}\n\n.my-3 {\n  margin-top: 0.75rem !important;\n  margin-bottom: 0.75rem !important;\n}\n\n.m-4 {\n  margin: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1rem !important;\n}\n\n.mr-4 {\n  margin-right: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1rem !important;\n}\n\n.ml-4 {\n  margin-left: 1rem !important;\n}\n\n.mx-4 {\n  margin-left: 1rem !important;\n  margin-right: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.m-5 {\n  margin: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 1.5rem !important;\n}\n\n.mr-5 {\n  margin-right: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 1.5rem !important;\n}\n\n.ml-5 {\n  margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-left: 1.5rem !important;\n  margin-right: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.m-6 {\n  margin: 3rem !important;\n}\n\n.mt-6 {\n  margin-top: 3rem !important;\n}\n\n.mr-6 {\n  margin-right: 3rem !important;\n}\n\n.mb-6 {\n  margin-bottom: 3rem !important;\n}\n\n.ml-6 {\n  margin-left: 3rem !important;\n}\n\n.mx-6 {\n  margin-left: 3rem !important;\n  margin-right: 3rem !important;\n}\n\n.my-6 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.mr-auto {\n  margin-right: auto !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ml-auto {\n  margin-left: auto !important;\n}\n\n.mx-auto {\n  margin-left: auto !important;\n  margin-right: auto !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pr-0 {\n  padding-right: 0 !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pl-0 {\n  padding-left: 0 !important;\n}\n\n.px-0 {\n  padding-left: 0 !important;\n  padding-right: 0 !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pr-1 {\n  padding-right: 0.25rem !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pl-1 {\n  padding-left: 0.25rem !important;\n}\n\n.px-1 {\n  padding-left: 0.25rem !important;\n  padding-right: 0.25rem !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pr-2 {\n  padding-right: 0.5rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pl-2 {\n  padding-left: 0.5rem !important;\n}\n\n.px-2 {\n  padding-left: 0.5rem !important;\n  padding-right: 0.5rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 0.75rem !important;\n}\n\n.pt-3 {\n  padding-top: 0.75rem !important;\n}\n\n.pr-3 {\n  padding-right: 0.75rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 0.75rem !important;\n}\n\n.pl-3 {\n  padding-left: 0.75rem !important;\n}\n\n.px-3 {\n  padding-left: 0.75rem !important;\n  padding-right: 0.75rem !important;\n}\n\n.py-3 {\n  padding-top: 0.75rem !important;\n  padding-bottom: 0.75rem !important;\n}\n\n.p-4 {\n  padding: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1rem !important;\n}\n\n.pr-4 {\n  padding-right: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1rem !important;\n}\n\n.pl-4 {\n  padding-left: 1rem !important;\n}\n\n.px-4 {\n  padding-left: 1rem !important;\n  padding-right: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.p-5 {\n  padding: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 1.5rem !important;\n}\n\n.pr-5 {\n  padding-right: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pl-5 {\n  padding-left: 1.5rem !important;\n}\n\n.px-5 {\n  padding-left: 1.5rem !important;\n  padding-right: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.p-6 {\n  padding: 3rem !important;\n}\n\n.pt-6 {\n  padding-top: 3rem !important;\n}\n\n.pr-6 {\n  padding-right: 3rem !important;\n}\n\n.pb-6 {\n  padding-bottom: 3rem !important;\n}\n\n.pl-6 {\n  padding-left: 3rem !important;\n}\n\n.px-6 {\n  padding-left: 3rem !important;\n  padding-right: 3rem !important;\n}\n\n.py-6 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.p-auto {\n  padding: auto !important;\n}\n\n.pt-auto {\n  padding-top: auto !important;\n}\n\n.pr-auto {\n  padding-right: auto !important;\n}\n\n.pb-auto {\n  padding-bottom: auto !important;\n}\n\n.pl-auto {\n  padding-left: auto !important;\n}\n\n.px-auto {\n  padding-left: auto !important;\n  padding-right: auto !important;\n}\n\n.py-auto {\n  padding-top: auto !important;\n  padding-bottom: auto !important;\n}\n\n.is-size-1 {\n  font-size: 3rem !important;\n}\n\n.is-size-2 {\n  font-size: 2.5rem !important;\n}\n\n.is-size-3 {\n  font-size: 2rem !important;\n}\n\n.is-size-4 {\n  font-size: 1.5rem !important;\n}\n\n.is-size-5 {\n  font-size: 1.25rem !important;\n}\n\n.is-size-6 {\n  font-size: 1rem !important;\n}\n\n.is-size-7 {\n  font-size: 0.75rem !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-size-1-mobile {\n    font-size: 3rem !important;\n  }\n  .is-size-2-mobile {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-mobile {\n    font-size: 2rem !important;\n  }\n  .is-size-4-mobile {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-mobile {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-mobile {\n    font-size: 1rem !important;\n  }\n  .is-size-7-mobile {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-size-1-tablet {\n    font-size: 3rem !important;\n  }\n  .is-size-2-tablet {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-tablet {\n    font-size: 2rem !important;\n  }\n  .is-size-4-tablet {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-tablet {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-tablet {\n    font-size: 1rem !important;\n  }\n  .is-size-7-tablet {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-size-1-touch {\n    font-size: 3rem !important;\n  }\n  .is-size-2-touch {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-touch {\n    font-size: 2rem !important;\n  }\n  .is-size-4-touch {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-touch {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-touch {\n    font-size: 1rem !important;\n  }\n  .is-size-7-touch {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-size-1-desktop {\n    font-size: 3rem !important;\n  }\n  .is-size-2-desktop {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-desktop {\n    font-size: 2rem !important;\n  }\n  .is-size-4-desktop {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-desktop {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-desktop {\n    font-size: 1rem !important;\n  }\n  .is-size-7-desktop {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-size-1-widescreen {\n    font-size: 3rem !important;\n  }\n  .is-size-2-widescreen {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-widescreen {\n    font-size: 2rem !important;\n  }\n  .is-size-4-widescreen {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-widescreen {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-widescreen {\n    font-size: 1rem !important;\n  }\n  .is-size-7-widescreen {\n    font-size: 0.75rem !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-size-1-fullhd {\n    font-size: 3rem !important;\n  }\n  .is-size-2-fullhd {\n    font-size: 2.5rem !important;\n  }\n  .is-size-3-fullhd {\n    font-size: 2rem !important;\n  }\n  .is-size-4-fullhd {\n    font-size: 1.5rem !important;\n  }\n  .is-size-5-fullhd {\n    font-size: 1.25rem !important;\n  }\n  .is-size-6-fullhd {\n    font-size: 1rem !important;\n  }\n  .is-size-7-fullhd {\n    font-size: 0.75rem !important;\n  }\n}\n\n.has-text-centered {\n  text-align: center !important;\n}\n\n.has-text-justified {\n  text-align: justify !important;\n}\n\n.has-text-left {\n  text-align: left !important;\n}\n\n.has-text-right {\n  text-align: right !important;\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-centered-mobile {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-centered-tablet {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-centered-tablet-only {\n    text-align: center !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-centered-touch {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-centered-desktop {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-centered-desktop-only {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-centered-widescreen {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-centered-widescreen-only {\n    text-align: center !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-centered-fullhd {\n    text-align: center !important;\n  }\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-justified-mobile {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-justified-tablet {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-justified-tablet-only {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-justified-touch {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-justified-desktop {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-justified-desktop-only {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-justified-widescreen {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-justified-widescreen-only {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-justified-fullhd {\n    text-align: justify !important;\n  }\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-left-mobile {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-left-tablet {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-left-tablet-only {\n    text-align: left !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-left-touch {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-left-desktop {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-left-desktop-only {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-left-widescreen {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-left-widescreen-only {\n    text-align: left !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-left-fullhd {\n    text-align: left !important;\n  }\n}\n\n@media screen and (max-width: 768px) {\n  .has-text-right-mobile {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .has-text-right-tablet {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .has-text-right-tablet-only {\n    text-align: right !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .has-text-right-touch {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .has-text-right-desktop {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .has-text-right-desktop-only {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .has-text-right-widescreen {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .has-text-right-widescreen-only {\n    text-align: right !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .has-text-right-fullhd {\n    text-align: right !important;\n  }\n}\n\n.is-capitalized {\n  text-transform: capitalize !important;\n}\n\n.is-lowercase {\n  text-transform: lowercase !important;\n}\n\n.is-uppercase {\n  text-transform: uppercase !important;\n}\n\n.is-italic {\n  font-style: italic !important;\n}\n\n.is-underlined {\n  text-decoration: underline !important;\n}\n\n.has-text-weight-light {\n  font-weight: 300 !important;\n}\n\n.has-text-weight-normal {\n  font-weight: 400 !important;\n}\n\n.has-text-weight-medium {\n  font-weight: 500 !important;\n}\n\n.has-text-weight-semibold {\n  font-weight: 600 !important;\n}\n\n.has-text-weight-bold {\n  font-weight: 700 !important;\n}\n\n.is-family-primary {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif !important;\n}\n\n.is-family-secondary {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif !important;\n}\n\n.is-family-sans-serif {\n  font-family: BlinkMacSystemFont, -apple-system, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", \"Helvetica\", \"Arial\", sans-serif !important;\n}\n\n.is-family-monospace {\n  font-family: monospace !important;\n}\n\n.is-family-code {\n  font-family: monospace !important;\n}\n\n.is-block {\n  display: block !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-block-mobile {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-block-tablet {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-block-tablet-only {\n    display: block !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-block-touch {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-block-desktop {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-block-desktop-only {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-block-widescreen {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-block-widescreen-only {\n    display: block !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-block-fullhd {\n    display: block !important;\n  }\n}\n\n.is-flex {\n  display: flex !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-flex-mobile {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-flex-tablet {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-flex-tablet-only {\n    display: flex !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-flex-touch {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-flex-desktop {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-flex-desktop-only {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-flex-widescreen {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-flex-widescreen-only {\n    display: flex !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-flex-fullhd {\n    display: flex !important;\n  }\n}\n\n.is-inline {\n  display: inline !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-inline-mobile {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-inline-tablet {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-inline-tablet-only {\n    display: inline !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-inline-touch {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-inline-desktop {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-inline-desktop-only {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-inline-widescreen {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-inline-widescreen-only {\n    display: inline !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-inline-fullhd {\n    display: inline !important;\n  }\n}\n\n.is-inline-block {\n  display: inline-block !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-inline-block-mobile {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-inline-block-tablet {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-inline-block-tablet-only {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-inline-block-touch {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-inline-block-desktop {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-inline-block-desktop-only {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-inline-block-widescreen {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-inline-block-widescreen-only {\n    display: inline-block !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-inline-block-fullhd {\n    display: inline-block !important;\n  }\n}\n\n.is-inline-flex {\n  display: inline-flex !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-inline-flex-mobile {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-inline-flex-tablet {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-inline-flex-tablet-only {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-inline-flex-touch {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-inline-flex-desktop {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-inline-flex-desktop-only {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-inline-flex-widescreen {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-inline-flex-widescreen-only {\n    display: inline-flex !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-inline-flex-fullhd {\n    display: inline-flex !important;\n  }\n}\n\n.is-hidden {\n  display: none !important;\n}\n\n.is-sr-only {\n  border: none !important;\n  clip: rect(0, 0, 0, 0) !important;\n  height: 0.01em !important;\n  overflow: hidden !important;\n  padding: 0 !important;\n  position: absolute !important;\n  white-space: nowrap !important;\n  width: 0.01em !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-hidden-mobile {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-hidden-tablet {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-hidden-tablet-only {\n    display: none !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-hidden-touch {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-hidden-desktop {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-hidden-desktop-only {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-hidden-widescreen {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-hidden-widescreen-only {\n    display: none !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-hidden-fullhd {\n    display: none !important;\n  }\n}\n\n.is-invisible {\n  visibility: hidden !important;\n}\n\n@media screen and (max-width: 768px) {\n  .is-invisible-mobile {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .is-invisible-tablet {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 769px) and (max-width: 1023px) {\n  .is-invisible-tablet-only {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (max-width: 1023px) {\n  .is-invisible-touch {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1024px) {\n  .is-invisible-desktop {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1024px) and (max-width: 1215px) {\n  .is-invisible-desktop-only {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1216px) {\n  .is-invisible-widescreen {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1216px) and (max-width: 1407px) {\n  .is-invisible-widescreen-only {\n    visibility: hidden !important;\n  }\n}\n\n@media screen and (min-width: 1408px) {\n  .is-invisible-fullhd {\n    visibility: hidden !important;\n  }\n}\n\n/* Bulma Layout */\n.hero {\n  align-items: stretch;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n}\n\n.hero .navbar {\n  background: none;\n}\n\n.hero .tabs ul {\n  border-bottom: none;\n}\n\n.hero.is-white {\n  background-color: white;\n  color: #0a0a0a;\n}\n\n.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-white strong {\n  color: inherit;\n}\n\n.hero.is-white .title {\n  color: #0a0a0a;\n}\n\n.hero.is-white .subtitle {\n  color: rgba(10, 10, 10, 0.9);\n}\n\n.hero.is-white .subtitle a:not(.button),\n.hero.is-white .subtitle strong {\n  color: #0a0a0a;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-white .navbar-menu {\n    background-color: white;\n  }\n}\n\n.hero.is-white .navbar-item,\n.hero.is-white .navbar-link {\n  color: rgba(10, 10, 10, 0.7);\n}\n\n.hero.is-white a.navbar-item:hover, .hero.is-white a.navbar-item.is-active,\n.hero.is-white .navbar-link:hover,\n.hero.is-white .navbar-link.is-active {\n  background-color: #f2f2f2;\n  color: #0a0a0a;\n}\n\n.hero.is-white .tabs a {\n  color: #0a0a0a;\n  opacity: 0.9;\n}\n\n.hero.is-white .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-white .tabs li.is-active a {\n  color: white !important;\n  opacity: 1;\n}\n\n.hero.is-white .tabs.is-boxed a, .hero.is-white .tabs.is-toggle a {\n  color: #0a0a0a;\n}\n\n.hero.is-white .tabs.is-boxed a:hover, .hero.is-white .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-white .tabs.is-boxed li.is-active a, .hero.is-white .tabs.is-boxed li.is-active a:hover, .hero.is-white .tabs.is-toggle li.is-active a, .hero.is-white .tabs.is-toggle li.is-active a:hover {\n  background-color: #0a0a0a;\n  border-color: #0a0a0a;\n  color: white;\n}\n\n.hero.is-white.is-bold {\n  background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-white.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%);\n  }\n}\n\n.hero.is-black {\n  background-color: #0a0a0a;\n  color: white;\n}\n\n.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-black strong {\n  color: inherit;\n}\n\n.hero.is-black .title {\n  color: white;\n}\n\n.hero.is-black .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-black .subtitle a:not(.button),\n.hero.is-black .subtitle strong {\n  color: white;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-black .navbar-menu {\n    background-color: #0a0a0a;\n  }\n}\n\n.hero.is-black .navbar-item,\n.hero.is-black .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-black a.navbar-item:hover, .hero.is-black a.navbar-item.is-active,\n.hero.is-black .navbar-link:hover,\n.hero.is-black .navbar-link.is-active {\n  background-color: black;\n  color: white;\n}\n\n.hero.is-black .tabs a {\n  color: white;\n  opacity: 0.9;\n}\n\n.hero.is-black .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-black .tabs li.is-active a {\n  color: #0a0a0a !important;\n  opacity: 1;\n}\n\n.hero.is-black .tabs.is-boxed a, .hero.is-black .tabs.is-toggle a {\n  color: white;\n}\n\n.hero.is-black .tabs.is-boxed a:hover, .hero.is-black .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-black .tabs.is-boxed li.is-active a, .hero.is-black .tabs.is-boxed li.is-active a:hover, .hero.is-black .tabs.is-toggle li.is-active a, .hero.is-black .tabs.is-toggle li.is-active a:hover {\n  background-color: white;\n  border-color: white;\n  color: #0a0a0a;\n}\n\n.hero.is-black.is-bold {\n  background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-black.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%);\n  }\n}\n\n.hero.is-light {\n  background-color: whitesmoke;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-light strong {\n  color: inherit;\n}\n\n.hero.is-light .title {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light .subtitle {\n  color: rgba(0, 0, 0, 0.9);\n}\n\n.hero.is-light .subtitle a:not(.button),\n.hero.is-light .subtitle strong {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-light .navbar-menu {\n    background-color: whitesmoke;\n  }\n}\n\n.hero.is-light .navbar-item,\n.hero.is-light .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light a.navbar-item:hover, .hero.is-light a.navbar-item.is-active,\n.hero.is-light .navbar-link:hover,\n.hero.is-light .navbar-link.is-active {\n  background-color: #e8e8e8;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light .tabs a {\n  color: rgba(0, 0, 0, 0.7);\n  opacity: 0.9;\n}\n\n.hero.is-light .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-light .tabs li.is-active a {\n  color: whitesmoke !important;\n  opacity: 1;\n}\n\n.hero.is-light .tabs.is-boxed a, .hero.is-light .tabs.is-toggle a {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-light .tabs.is-boxed a:hover, .hero.is-light .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-light .tabs.is-boxed li.is-active a, .hero.is-light .tabs.is-boxed li.is-active a:hover, .hero.is-light .tabs.is-toggle li.is-active a, .hero.is-light .tabs.is-toggle li.is-active a:hover {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: rgba(0, 0, 0, 0.7);\n  color: whitesmoke;\n}\n\n.hero.is-light.is-bold {\n  background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-light.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%);\n  }\n}\n\n.hero.is-dark {\n  background-color: #363636;\n  color: #fff;\n}\n\n.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-dark strong {\n  color: inherit;\n}\n\n.hero.is-dark .title {\n  color: #fff;\n}\n\n.hero.is-dark .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-dark .subtitle a:not(.button),\n.hero.is-dark .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-dark .navbar-menu {\n    background-color: #363636;\n  }\n}\n\n.hero.is-dark .navbar-item,\n.hero.is-dark .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-dark a.navbar-item:hover, .hero.is-dark a.navbar-item.is-active,\n.hero.is-dark .navbar-link:hover,\n.hero.is-dark .navbar-link.is-active {\n  background-color: #292929;\n  color: #fff;\n}\n\n.hero.is-dark .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-dark .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-dark .tabs li.is-active a {\n  color: #363636 !important;\n  opacity: 1;\n}\n\n.hero.is-dark .tabs.is-boxed a, .hero.is-dark .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-dark .tabs.is-boxed a:hover, .hero.is-dark .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-dark .tabs.is-boxed li.is-active a, .hero.is-dark .tabs.is-boxed li.is-active a:hover, .hero.is-dark .tabs.is-toggle li.is-active a, .hero.is-dark .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #363636;\n}\n\n.hero.is-dark.is-bold {\n  background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-dark.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%);\n  }\n}\n\n.hero.is-primary {\n  background-color: #00d1b2;\n  color: #fff;\n}\n\n.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-primary strong {\n  color: inherit;\n}\n\n.hero.is-primary .title {\n  color: #fff;\n}\n\n.hero.is-primary .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-primary .subtitle a:not(.button),\n.hero.is-primary .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-primary .navbar-menu {\n    background-color: #00d1b2;\n  }\n}\n\n.hero.is-primary .navbar-item,\n.hero.is-primary .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-primary a.navbar-item:hover, .hero.is-primary a.navbar-item.is-active,\n.hero.is-primary .navbar-link:hover,\n.hero.is-primary .navbar-link.is-active {\n  background-color: #00b89c;\n  color: #fff;\n}\n\n.hero.is-primary .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-primary .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-primary .tabs li.is-active a {\n  color: #00d1b2 !important;\n  opacity: 1;\n}\n\n.hero.is-primary .tabs.is-boxed a, .hero.is-primary .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-primary .tabs.is-boxed a:hover, .hero.is-primary .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-primary .tabs.is-boxed li.is-active a, .hero.is-primary .tabs.is-boxed li.is-active a:hover, .hero.is-primary .tabs.is-toggle li.is-active a, .hero.is-primary .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #00d1b2;\n}\n\n.hero.is-primary.is-bold {\n  background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-primary.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%);\n  }\n}\n\n.hero.is-link {\n  background-color: #485fc7;\n  color: #fff;\n}\n\n.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-link strong {\n  color: inherit;\n}\n\n.hero.is-link .title {\n  color: #fff;\n}\n\n.hero.is-link .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-link .subtitle a:not(.button),\n.hero.is-link .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-link .navbar-menu {\n    background-color: #485fc7;\n  }\n}\n\n.hero.is-link .navbar-item,\n.hero.is-link .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-link a.navbar-item:hover, .hero.is-link a.navbar-item.is-active,\n.hero.is-link .navbar-link:hover,\n.hero.is-link .navbar-link.is-active {\n  background-color: #3a51bb;\n  color: #fff;\n}\n\n.hero.is-link .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-link .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-link .tabs li.is-active a {\n  color: #485fc7 !important;\n  opacity: 1;\n}\n\n.hero.is-link .tabs.is-boxed a, .hero.is-link .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-link .tabs.is-boxed a:hover, .hero.is-link .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-link .tabs.is-boxed li.is-active a, .hero.is-link .tabs.is-boxed li.is-active a:hover, .hero.is-link .tabs.is-toggle li.is-active a, .hero.is-link .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #485fc7;\n}\n\n.hero.is-link.is-bold {\n  background-image: linear-gradient(141deg, #2959b3 0%, #485fc7 71%, #5658d2 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-link.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #2959b3 0%, #485fc7 71%, #5658d2 100%);\n  }\n}\n\n.hero.is-info {\n  background-color: #3e8ed0;\n  color: #fff;\n}\n\n.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-info strong {\n  color: inherit;\n}\n\n.hero.is-info .title {\n  color: #fff;\n}\n\n.hero.is-info .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-info .subtitle a:not(.button),\n.hero.is-info .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-info .navbar-menu {\n    background-color: #3e8ed0;\n  }\n}\n\n.hero.is-info .navbar-item,\n.hero.is-info .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-info a.navbar-item:hover, .hero.is-info a.navbar-item.is-active,\n.hero.is-info .navbar-link:hover,\n.hero.is-info .navbar-link.is-active {\n  background-color: #3082c5;\n  color: #fff;\n}\n\n.hero.is-info .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-info .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-info .tabs li.is-active a {\n  color: #3e8ed0 !important;\n  opacity: 1;\n}\n\n.hero.is-info .tabs.is-boxed a, .hero.is-info .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-info .tabs.is-boxed a:hover, .hero.is-info .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-info .tabs.is-boxed li.is-active a, .hero.is-info .tabs.is-boxed li.is-active a:hover, .hero.is-info .tabs.is-toggle li.is-active a, .hero.is-info .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #3e8ed0;\n}\n\n.hero.is-info.is-bold {\n  background-image: linear-gradient(141deg, #208fbc 0%, #3e8ed0 71%, #4d83db 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-info.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #208fbc 0%, #3e8ed0 71%, #4d83db 100%);\n  }\n}\n\n.hero.is-success {\n  background-color: #48c78e;\n  color: #fff;\n}\n\n.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-success strong {\n  color: inherit;\n}\n\n.hero.is-success .title {\n  color: #fff;\n}\n\n.hero.is-success .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-success .subtitle a:not(.button),\n.hero.is-success .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-success .navbar-menu {\n    background-color: #48c78e;\n  }\n}\n\n.hero.is-success .navbar-item,\n.hero.is-success .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-success a.navbar-item:hover, .hero.is-success a.navbar-item.is-active,\n.hero.is-success .navbar-link:hover,\n.hero.is-success .navbar-link.is-active {\n  background-color: #3abb81;\n  color: #fff;\n}\n\n.hero.is-success .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-success .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-success .tabs li.is-active a {\n  color: #48c78e !important;\n  opacity: 1;\n}\n\n.hero.is-success .tabs.is-boxed a, .hero.is-success .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-success .tabs.is-boxed a:hover, .hero.is-success .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-success .tabs.is-boxed li.is-active a, .hero.is-success .tabs.is-boxed li.is-active a:hover, .hero.is-success .tabs.is-toggle li.is-active a, .hero.is-success .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #48c78e;\n}\n\n.hero.is-success.is-bold {\n  background-image: linear-gradient(141deg, #29b35e 0%, #48c78e 71%, #56d2af 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-success.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #29b35e 0%, #48c78e 71%, #56d2af 100%);\n  }\n}\n\n.hero.is-warning {\n  background-color: #ffe08a;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-warning strong {\n  color: inherit;\n}\n\n.hero.is-warning .title {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning .subtitle {\n  color: rgba(0, 0, 0, 0.9);\n}\n\n.hero.is-warning .subtitle a:not(.button),\n.hero.is-warning .subtitle strong {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-warning .navbar-menu {\n    background-color: #ffe08a;\n  }\n}\n\n.hero.is-warning .navbar-item,\n.hero.is-warning .navbar-link {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning a.navbar-item:hover, .hero.is-warning a.navbar-item.is-active,\n.hero.is-warning .navbar-link:hover,\n.hero.is-warning .navbar-link.is-active {\n  background-color: #ffd970;\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning .tabs a {\n  color: rgba(0, 0, 0, 0.7);\n  opacity: 0.9;\n}\n\n.hero.is-warning .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-warning .tabs li.is-active a {\n  color: #ffe08a !important;\n  opacity: 1;\n}\n\n.hero.is-warning .tabs.is-boxed a, .hero.is-warning .tabs.is-toggle a {\n  color: rgba(0, 0, 0, 0.7);\n}\n\n.hero.is-warning .tabs.is-boxed a:hover, .hero.is-warning .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-warning .tabs.is-boxed li.is-active a, .hero.is-warning .tabs.is-boxed li.is-active a:hover, .hero.is-warning .tabs.is-toggle li.is-active a, .hero.is-warning .tabs.is-toggle li.is-active a:hover {\n  background-color: rgba(0, 0, 0, 0.7);\n  border-color: rgba(0, 0, 0, 0.7);\n  color: #ffe08a;\n}\n\n.hero.is-warning.is-bold {\n  background-image: linear-gradient(141deg, #ffb657 0%, #ffe08a 71%, #fff6a3 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-warning.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #ffb657 0%, #ffe08a 71%, #fff6a3 100%);\n  }\n}\n\n.hero.is-danger {\n  background-color: #f14668;\n  color: #fff;\n}\n\n.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),\n.hero.is-danger strong {\n  color: inherit;\n}\n\n.hero.is-danger .title {\n  color: #fff;\n}\n\n.hero.is-danger .subtitle {\n  color: rgba(255, 255, 255, 0.9);\n}\n\n.hero.is-danger .subtitle a:not(.button),\n.hero.is-danger .subtitle strong {\n  color: #fff;\n}\n\n@media screen and (max-width: 1023px) {\n  .hero.is-danger .navbar-menu {\n    background-color: #f14668;\n  }\n}\n\n.hero.is-danger .navbar-item,\n.hero.is-danger .navbar-link {\n  color: rgba(255, 255, 255, 0.7);\n}\n\n.hero.is-danger a.navbar-item:hover, .hero.is-danger a.navbar-item.is-active,\n.hero.is-danger .navbar-link:hover,\n.hero.is-danger .navbar-link.is-active {\n  background-color: #ef2e55;\n  color: #fff;\n}\n\n.hero.is-danger .tabs a {\n  color: #fff;\n  opacity: 0.9;\n}\n\n.hero.is-danger .tabs a:hover {\n  opacity: 1;\n}\n\n.hero.is-danger .tabs li.is-active a {\n  color: #f14668 !important;\n  opacity: 1;\n}\n\n.hero.is-danger .tabs.is-boxed a, .hero.is-danger .tabs.is-toggle a {\n  color: #fff;\n}\n\n.hero.is-danger .tabs.is-boxed a:hover, .hero.is-danger .tabs.is-toggle a:hover {\n  background-color: rgba(10, 10, 10, 0.1);\n}\n\n.hero.is-danger .tabs.is-boxed li.is-active a, .hero.is-danger .tabs.is-boxed li.is-active a:hover, .hero.is-danger .tabs.is-toggle li.is-active a, .hero.is-danger .tabs.is-toggle li.is-active a:hover {\n  background-color: #fff;\n  border-color: #fff;\n  color: #f14668;\n}\n\n.hero.is-danger.is-bold {\n  background-image: linear-gradient(141deg, #fa0a62 0%, #f14668 71%, #f7595f 100%);\n}\n\n@media screen and (max-width: 768px) {\n  .hero.is-danger.is-bold .navbar-menu {\n    background-image: linear-gradient(141deg, #fa0a62 0%, #f14668 71%, #f7595f 100%);\n  }\n}\n\n.hero.is-small .hero-body {\n  padding: 1.5rem;\n}\n\n@media screen and (min-width: 769px), print {\n  .hero.is-medium .hero-body {\n    padding: 9rem 4.5rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .hero.is-large .hero-body {\n    padding: 18rem 6rem;\n  }\n}\n\n.hero.is-halfheight .hero-body, .hero.is-fullheight .hero-body, .hero.is-fullheight-with-navbar .hero-body {\n  align-items: center;\n  display: flex;\n}\n\n.hero.is-halfheight .hero-body > .container, .hero.is-fullheight .hero-body > .container, .hero.is-fullheight-with-navbar .hero-body > .container {\n  flex-grow: 1;\n  flex-shrink: 1;\n}\n\n.hero.is-halfheight {\n  min-height: 50vh;\n}\n\n.hero.is-fullheight {\n  min-height: 100vh;\n}\n\n.hero-video {\n  overflow: hidden;\n}\n\n.hero-video video {\n  left: 50%;\n  min-height: 100%;\n  min-width: 100%;\n  position: absolute;\n  top: 50%;\n  transform: translate3d(-50%, -50%, 0);\n}\n\n.hero-video.is-transparent {\n  opacity: 0.3;\n}\n\n@media screen and (max-width: 768px) {\n  .hero-video {\n    display: none;\n  }\n}\n\n.hero-buttons {\n  margin-top: 1.5rem;\n}\n\n@media screen and (max-width: 768px) {\n  .hero-buttons .button {\n    display: flex;\n  }\n  .hero-buttons .button:not(:last-child) {\n    margin-bottom: 0.75rem;\n  }\n}\n\n@media screen and (min-width: 769px), print {\n  .hero-buttons {\n    display: flex;\n    justify-content: center;\n  }\n  .hero-buttons .button:not(:last-child) {\n    margin-right: 1.5rem;\n  }\n}\n\n.hero-head,\n.hero-foot {\n  flex-grow: 0;\n  flex-shrink: 0;\n}\n\n.hero-body {\n  flex-grow: 1;\n  flex-shrink: 0;\n  padding: 3rem 1.5rem;\n}\n\n@media screen and (min-width: 769px), print {\n  .hero-body {\n    padding: 3rem 3rem;\n  }\n}\n\n.section {\n  padding: 3rem 1.5rem;\n}\n\n@media screen and (min-width: 1024px) {\n  .section {\n    padding: 3rem 3rem;\n  }\n  .section.is-medium {\n    padding: 9rem 4.5rem;\n  }\n  .section.is-large {\n    padding: 18rem 6rem;\n  }\n}\n\n.footer {\n  background-color: #fafafa;\n  padding: 3rem 1.5rem 6rem;\n}\n/*# sourceMappingURL=bulma.css.map */"
  },
  {
    "path": "examples/counter-basic/assets/favicon/about.txt",
    "content": "This favicon was generated using the following font:\n\n- Font Title: Leckerli One\n- Font Author: Copyright (c) 2011 Gesine Todt (www.gesine-todt.de), with Reserved Font Names \"Leckerli\"\n- Font Source: http://fonts.gstatic.com/s/leckerlione/v16/V8mCoQH8VCsNttEnxnGQ-1itLZxcBtItFw.ttf\n- Font License: SIL Open Font License, 1.1 (http://scripts.sil.org/OFL))\n"
  },
  {
    "path": "examples/counter-basic/assets/favicon/site.webmanifest",
    "content": "{\"name\":\"\",\"short_name\":\"\",\"icons\":[{\"src\":\"/assets/favicon/android-chrome-192x192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\"},{\"src\":\"/assets/favicon/android-chrome-512x512.png\",\"sizes\":\"512x512\",\"type\":\"image/png\"}],\"theme_color\":\"#ffffff\",\"background_color\":\"#ffffff\",\"display\":\"standalone\"}\n"
  },
  {
    "path": "examples/counter-basic/components.templ",
    "content": "package main\n\nimport \"strconv\"\n\ntempl counts(global, user int) {\n\t<div>Global: { strconv.Itoa(global) }</div>\n\t<div>User: { strconv.Itoa(user) }</div>\n}\n\ntempl form() {\n\t<form action=\"/\" method=\"POST\">\n\t\t<div><button type=\"submit\" name=\"global\" value=\"global\">Global</button></div>\n\t\t<div><button type=\"submit\" name=\"user\" value=\"user\">User</button></div>\n\t</form>\n}\n\ntempl page(global, user int) {\n\t<html>\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<title>Counts</title>\n\t\t\t<link rel=\"stylesheet\" href=\"/assets/bulma.min.css\"/>\n\t\t\t<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/assets/favicon/apple-touch-icon.png\"/>\n\t\t\t<link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/assets/favicon/favicon-32x32.png\"/>\n\t\t\t<link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/assets/favicon/favicon-16x16.png\"/>\n\t\t\t<link rel=\"manifest\" href=\"/assets/favicon/site.webmanifest\"/>\n\t\t</head>\n\t\t<body class=\"bg-gray-100\">\n\t\t\t<header class=\"hero is-primary\">\n\t\t\t\t<div class=\"hero-body\">\n\t\t\t\t\t<div class=\"container\">\n\t\t\t\t\t\t<h1 class=\"title\">Counts</h1>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</header>\n\t\t\t<section class=\"section\">\n\t\t\t\t<div class=\"container\">\n\t\t\t\t\t<div class=\"columns is-centered\">\n\t\t\t\t\t\t<div class=\"column is-half\">\n\t\t\t\t\t\t\t@counts(global, user)\n\t\t\t\t\t\t\t@form()\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/counter-basic/components_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"strconv\"\n\nfunc counts(global, user int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Global: \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(global))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/counter-basic/components.templ`, Line: 6, Col: 36}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div><div>User: \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(user))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/counter-basic/components.templ`, Line: 7, Col: 32}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc form() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<form action=\\\"/\\\" method=\\\"POST\\\"><div><button type=\\\"submit\\\" name=\\\"global\\\" value=\\\"global\\\">Global</button></div><div><button type=\\\"submit\\\" name=\\\"user\\\" value=\\\"user\\\">User</button></div></form>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc page(global, user int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<html><head><meta charset=\\\"UTF-8\\\"><meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"><title>Counts</title><link rel=\\\"stylesheet\\\" href=\\\"/assets/bulma.min.css\\\"><link rel=\\\"apple-touch-icon\\\" sizes=\\\"180x180\\\" href=\\\"/assets/favicon/apple-touch-icon.png\\\"><link rel=\\\"icon\\\" type=\\\"image/png\\\" sizes=\\\"32x32\\\" href=\\\"/assets/favicon/favicon-32x32.png\\\"><link rel=\\\"icon\\\" type=\\\"image/png\\\" sizes=\\\"16x16\\\" href=\\\"/assets/favicon/favicon-16x16.png\\\"><link rel=\\\"manifest\\\" href=\\\"/assets/favicon/site.webmanifest\\\"></head><body class=\\\"bg-gray-100\\\"><header class=\\\"hero is-primary\\\"><div class=\\\"hero-body\\\"><div class=\\\"container\\\"><h1 class=\\\"title\\\">Counts</h1></div></div></header><section class=\\\"section\\\"><div class=\\\"container\\\"><div class=\\\"columns is-centered\\\"><div class=\\\"column is-half\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = counts(global, user).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = form().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"</div></div></div></section></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/counter-basic/fly.toml",
    "content": "# fly.toml file generated for counter-basic on 2023-04-28T14:22:23+01:00\n\napp = \"counter-basic\"\nkill_signal = \"SIGINT\"\nkill_timeout = 5\nprimary_region = \"lhr\"\nprocesses = []\n\n[env]\n  PORT = \"8080\"\n\n[experimental]\n  auto_rollback = true\n\n[[services]]\n  http_checks = []\n  internal_port = 8080\n  processes = [\"app\"]\n  protocol = \"tcp\"\n  script_checks = []\n  [services.concurrency]\n    hard_limit = 25\n    soft_limit = 20\n    type = \"connections\"\n\n  [[services.ports]]\n    force_https = true\n    handlers = [\"http\"]\n    port = 80\n\n  [[services.ports]]\n    handlers = [\"tls\", \"http\"]\n    port = 443\n\n  [[services.tcp_checks]]\n    grace_period = \"1s\"\n    interval = \"15s\"\n    restart_limit = 0\n    timeout = \"2s\"\n"
  },
  {
    "path": "examples/counter-basic/go.mod",
    "content": "module github.com/a-h/templ/examples/counter-basic\n\ngo 1.25.0\n\nrequire github.com/a-h/templ v0.2.233\n\nrequire github.com/alexedwards/scs/v2 v2.8.0\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/counter-basic/go.sum",
    "content": "github.com/alexedwards/scs/v2 v2.8.0 h1:h31yUYoycPuL0zt14c0gd+oqxfRwIj6SOjHdKRZxhEw=\ngithub.com/alexedwards/scs/v2 v2.8.0/go.mod h1:ToaROZxyKukJKT/xLcVQAChi5k6+Pn1Gvmdl7h3RRj8=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/counter-basic/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/alexedwards/scs/v2\"\n)\n\ntype GlobalState struct {\n\tCount int\n}\n\nvar global GlobalState\nvar sessionManager *scs.SessionManager\n\nfunc getHandler(w http.ResponseWriter, r *http.Request) {\n\tuserCount := sessionManager.GetInt(r.Context(), \"count\")\n\tcomponent := page(global.Count, userCount)\n\tcomponent.Render(r.Context(), w)\n}\n\nfunc postHandler(w http.ResponseWriter, r *http.Request) {\n\t// Update state.\n\tr.ParseForm()\n\n\t// Check to see if the global button was pressed.\n\tif r.Form.Has(\"global\") {\n\t\tglobal.Count++\n\t}\n\tif r.Form.Has(\"user\") {\n\t\tcurrentCount := sessionManager.GetInt(r.Context(), \"count\")\n\t\tsessionManager.Put(r.Context(), \"count\", currentCount+1)\n\t}\n\n\t// Display the form.\n\tgetHandler(w, r)\n}\n\nfunc main() {\n\t// Initialize the session.\n\tsessionManager = scs.New()\n\tsessionManager.Lifetime = 24 * time.Hour\n\n\tmux := http.NewServeMux()\n\n\t// Handle POST and GET requests.\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.Method == http.MethodPost {\n\t\t\tpostHandler(w, r)\n\t\t\treturn\n\t\t}\n\t\tgetHandler(w, r)\n\t})\n\n\t// Include the static content.\n\tmux.Handle(\"/assets/\", http.StripPrefix(\"/assets/\", http.FileServer(http.Dir(\"assets\"))))\n\n\t// Add the middleware.\n\tmuxWithSessionMiddleware := sessionManager.LoadAndSave(mux)\n\n\t// Start the server.\n\tfmt.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\"127.0.0.1:8080\", muxWithSessionMiddleware); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "examples/external-libraries/components.templ",
    "content": "package main\n\nscript graph(data []TimeValue) {\n\tconst chart = LightweightCharts.createChart(document.body, { width: 400, height: 300 });\n\tconst lineSeries = chart.addLineSeries();\n\tlineSeries.setData(data);\n}\n\ntempl page(data []TimeValue) {\n\t<html>\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<title>Graphs</title>\n\t\t\t<script src=\"https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js\"></script>\n\t\t</head>\n\t\t<body onload={ graph(data) }></body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/external-libraries/components_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc graph(data []TimeValue) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_graph_c2ba`,\n\t\tFunction: `function __templ_graph_c2ba(data){const chart = LightweightCharts.createChart(document.body, { width: 400, height: 300 });\n\tconst lineSeries = chart.addLineSeries();\n\tlineSeries.setData(data);\n}`,\n\t\tCall:       templ.SafeScript(`__templ_graph_c2ba`, data),\n\t\tCallInline: templ.SafeScriptInline(`__templ_graph_c2ba`, data),\n\t}\n}\n\nfunc page(data []TimeValue) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<html><head><meta charset=\\\"UTF-8\\\"><meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"><title>Graphs</title><script src=\\\"https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js\\\"></script></head>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, graph(data))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<body onload=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.ComponentScript = graph(data)\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\"></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/external-libraries/go.mod",
    "content": "module github.com/a-h/templ/examples/external-libraries\n\ngo 1.25.0\n\nrequire github.com/a-h/templ v0.2.304\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/external-libraries/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/external-libraries/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype TimeValue struct {\n\tTime  string  `json:\"time\"`\n\tValue float64 `json:\"value\"`\n}\n\nfunc main() {\n\tmux := http.NewServeMux()\n\n\t// Handle template.\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tdata := []TimeValue{\n\t\t\t{Time: \"2019-04-11\", Value: 80.01},\n\t\t\t{Time: \"2019-04-12\", Value: 96.63},\n\t\t\t{Time: \"2019-04-13\", Value: 76.64},\n\t\t\t{Time: \"2019-04-14\", Value: 81.89},\n\t\t\t{Time: \"2019-04-15\", Value: 74.43},\n\t\t\t{Time: \"2019-04-16\", Value: 80.01},\n\t\t\t{Time: \"2019-04-17\", Value: 96.63},\n\t\t\t{Time: \"2019-04-18\", Value: 76.64},\n\t\t\t{Time: \"2019-04-19\", Value: 81.89},\n\t\t\t{Time: \"2019-04-20\", Value: 74.43},\n\t\t}\n\t\tpage(data).Render(r.Context(), w)\n\t})\n\n\t// Start the server.\n\tfmt.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\":8080\", mux); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "examples/hello-world-ssr/hello.templ",
    "content": "package main\n\ntempl hello(name string) {\n\t<div>Hello, { name }</div>\n}\n"
  },
  {
    "path": "examples/hello-world-ssr/hello_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc hello(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Hello, \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/hello-world-ssr/hello.templ`, Line: 4, Col: 19}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/hello-world-ssr/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\tcomponent := hello(\"John\")\n\n\thttp.Handle(\"/\", templ.Handler(component))\n\n\tfmt.Println(\"Listening on :3000\")\n\tif err := http.ListenAndServe(\":3000\", nil); err != nil {\n\t\tlog.Fatalf(\"server error: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "examples/hello-world-static/hello.templ",
    "content": "package main\n\ntempl hello(name string) {\n\t<div>Hello, { name }</div>\n}\n"
  },
  {
    "path": "examples/hello-world-static/hello_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc hello(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Hello, \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/hello-world-static/hello.templ`, Line: 4, Col: 19}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/hello-world-static/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n)\n\nfunc main() {\n\tcomponent := hello(\"John\")\n\tif err := component.Render(context.Background(), os.Stdout); err != nil {\n\t\tlog.Fatalf(\"failed to render: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "examples/htmx-fragments/README.md",
    "content": "## Tasks\n\n### run\n\n```bash\ntempl generate --watch --proxy=\"http://localhost:8080\" --cmd=\"go run .\"\n```\n"
  },
  {
    "path": "examples/htmx-fragments/go.mod",
    "content": "module github.com/a-h/templ/examples/htmx-fragments\n\ngo 1.25.0\n\nrequire github.com/a-h/templ v0.2.747\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/htmx-fragments/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/htmx-fragments/main.templ",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"strconv\"\n)\n\ntype PageState struct {\n\tCounter int\n\tNext    int\n}\n\ntempl Page(state PageState) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<script src=\"https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js\"></script>\n\t\t\t<link rel=\"stylesheet\" href=\"https://unpkg.com/missing.css@1.1.3/dist/missing.min.css\"/>\n\t\t\t<title>Template Fragment Example</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>Template Fragment Example</h1>\n\t\t\t<p>\n\t\t\t\tThis page demonstrates how to create and serve \n\t\t\t\t<a href=\"https://htmx.org/essays/template-fragments/\">template fragments</a>\n\t\t\t\tusing <a href=\"https://templ.guide\">templ</a> in Go.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tThis is accomplished by using the \"templ.Fragment\" component, which lets you\n\t\t\t\tselect areas to include in the output.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tAdapted from https://gist.github.com/benpate/f92b77ea9b3a8503541eb4b9eb515d8a\n\t\t\t</p>\n\t\t\t<!-- Here's the fragment.  We can target it by executing the \"buttonOnly\" template. -->\n\t\t\t@templ.Fragment(\"buttonOnly\") {\n\t\t\t\t<button hx-get={ fmt.Sprintf(\"/?counter=%d&template=buttonOnly\", state.Next) } hx-swap=\"outerHTML\">\n\t\t\t\t\tThis Button Has Been Clicked { state.Counter } Times\n\t\t\t\t</button>\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n\n// handleRequest does the work to execute the template (or fragment) and serve the result.\n// It's mostly boilerplate, so don't get hung up on it.\nfunc handleRequest(w http.ResponseWriter, r *http.Request) {\n\t// Collect state info to pass to the template.\n\tvar state PageState\n\tstate.Counter, _ = strconv.Atoi(r.URL.Query().Get(\"counter\"))\n\tstate.Next = state.Counter + 1\n\n\t// If the template querystring paramater is set, render the pecific fragment.\n\tvar opts []func(*templ.ComponentHandler)\n\tif templateName := r.URL.Query().Get(\"template\"); templateName != \"\" {\n\t\topts = append(opts, templ.WithFragments(templateName))\n\t}\n\n\t// Render the template or fragment and serve it.\n\ttempl.Handler(Page(state), opts...).ServeHTTP(w, r)\n}\n\nfunc main() {\n\t// Handle the template.\n\thttp.HandleFunc(\"/\", handleRequest)\n\n\t// Start the server.\n\tfmt.Println(\"Server is running at http://localhost:8080\")\n\thttp.ListenAndServe(\"localhost:8080\", nil)\n}\n"
  },
  {
    "path": "examples/htmx-fragments/main_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"strconv\"\n)\n\ntype PageState struct {\n\tCounter int\n\tNext    int\n}\n\nfunc Page(state PageState) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype html><html><head><script src=\\\"https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js\\\"></script><link rel=\\\"stylesheet\\\" href=\\\"https://unpkg.com/missing.css@1.1.3/dist/missing.min.css\\\"><title>Template Fragment Example</title></head><body><h1>Template Fragment Example</h1><p>This page demonstrates how to create and serve  <a href=\\\"https://htmx.org/essays/template-fragments/\\\">template fragments</a> using <a href=\\\"https://templ.guide\\\">templ</a> in Go.</p><p>This is accomplished by using the \\\"templ.Fragment\\\" component, which lets you select areas to include in the output.</p><p>Adapted from https://gist.github.com/benpate/f92b77ea9b3a8503541eb4b9eb515d8a</p><!-- Here's the fragment.  We can target it by executing the \\\"buttonOnly\\\" template. -->\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<button hx-get=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(\"/?counter=%d&template=buttonOnly\", state.Next))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/htmx-fragments/main.templ`, Line: 38, Col: 80}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\" hx-swap=\\\"outerHTML\\\">This Button Has Been Clicked \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var4 string\n\t\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(state.Counter)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/htmx-fragments/main.templ`, Line: 39, Col: 49}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \" Times</button>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = templ.Fragment(\"buttonOnly\").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// handleRequest does the work to execute the template (or fragment) and serve the result.\n// It's mostly boilerplate, so don't get hung up on it.\nfunc handleRequest(w http.ResponseWriter, r *http.Request) {\n\t// Collect state info to pass to the template.\n\tvar state PageState\n\tstate.Counter, _ = strconv.Atoi(r.URL.Query().Get(\"counter\"))\n\tstate.Next = state.Counter + 1\n\n\t// If the template querystring paramater is set, render the pecific fragment.\n\tvar opts []func(*templ.ComponentHandler)\n\tif templateName := r.URL.Query().Get(\"template\"); templateName != \"\" {\n\t\topts = append(opts, templ.WithFragments(templateName))\n\t}\n\n\t// Render the template or fragment and serve it.\n\ttempl.Handler(Page(state), opts...).ServeHTTP(w, r)\n}\n\nfunc main() {\n\t// Handle the template.\n\thttp.HandleFunc(\"/\", handleRequest)\n\n\t// Start the server.\n\tfmt.Println(\"Server is running at http://localhost:8080\")\n\thttp.ListenAndServe(\"localhost:8080\", nil)\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/integration-chi/go.mod",
    "content": "module github.com/a-h/templ/examples/integration-chi\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.364\n\tgithub.com/go-chi/chi/v5 v5.2.2\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/integration-chi/go.sum",
    "content": "github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=\ngithub.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/integration-chi/home.templ",
    "content": "package main\n\ntempl Home() {\n\t<div>Hello World</div>\n}\n"
  },
  {
    "path": "examples/integration-chi/home_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Home() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Hello World</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/integration-chi/main.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/go-chi/chi/v5\"\n)\n\nfunc main() {\n\tr := chi.NewRouter()\n\tr.Get(\"/\", templ.Handler(Home()).ServeHTTP)\n\thttp.ListenAndServe(\":3000\", r)\n}\n"
  },
  {
    "path": "examples/integration-echo/go.mod",
    "content": "module github.com/a-h/templ/examples/integration-echo\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.663\n\tgithub.com/labstack/echo/v4 v4.14.0\n)\n\nrequire (\n\tgithub.com/labstack/gommon v0.4.2 // indirect\n\tgithub.com/mattn/go-colorable v0.1.14 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/valyala/bytebufferpool v1.0.0 // indirect\n\tgithub.com/valyala/fasttemplate v1.2.2 // indirect\n\tgolang.org/x/crypto v0.48.0 // indirect\n\tgolang.org/x/net v0.51.0 // indirect\n\tgolang.org/x/sys v0.41.0 // indirect\n\tgolang.org/x/text v0.34.0 // indirect\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/integration-echo/go.sum",
    "content": "github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/labstack/echo/v4 v4.14.0 h1:+tiMrDLxwv6u0oKtD03mv+V1vXXB3wCqPHJqPuIe+7M=\ngithub.com/labstack/echo/v4 v4.14.0/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c=\ngithub.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=\ngithub.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=\ngithub.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=\ngithub.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=\ngithub.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=\ngolang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=\ngolang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=\ngolang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=\ngolang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=\ngolang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=\ngolang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "examples/integration-echo/home.templ",
    "content": "package main\n\ntempl Home() {\n\t<div>Hello World</div>\n}\n"
  },
  {
    "path": "examples/integration-echo/home_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Home() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Hello World</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/integration-echo/main.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nfunc main() {\n\tapp := echo.New()\n\tapp.GET(\"/\", HomeHandler)\n\tapp.Logger.Fatal(app.Start(\":4000\"))\n}\n\n// This custom Render replaces Echo's echo.Context.Render() with templ's templ.Component.Render().\nfunc Render(ctx echo.Context, statusCode int, t templ.Component) error {\n\tbuf := templ.GetBuffer()\n\tdefer templ.ReleaseBuffer(buf)\n\n\tif err := t.Render(ctx.Request().Context(), buf); err != nil {\n\t\treturn err\n\t}\n\n\treturn ctx.HTML(statusCode, buf.String())\n}\n\nfunc HomeHandler(c echo.Context) error {\n\treturn Render(c, http.StatusOK, Home())\n}\n"
  },
  {
    "path": "examples/integration-gin/gintemplrenderer/renderer.go",
    "content": "package gintemplrenderer\n\nimport (\n\t\"context\"\n\t\"github.com/gin-gonic/gin/render\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nvar Default = &HTMLTemplRenderer{}\n\ntype HTMLTemplRenderer struct {\n\tFallbackHtmlRenderer render.HTMLRender\n}\n\nfunc (r *HTMLTemplRenderer) Instance(s string, d any) render.Render {\n\ttemplData, ok := d.(templ.Component)\n\tif !ok {\n\t\tif r.FallbackHtmlRenderer != nil {\n\t\t\treturn r.FallbackHtmlRenderer.Instance(s, d)\n\t\t}\n\t}\n\treturn &Renderer{\n\t\tCtx:       context.Background(),\n\t\tStatus:    -1,\n\t\tComponent: templData,\n\t}\n}\n\nfunc New(ctx context.Context, status int, component templ.Component) *Renderer {\n\treturn &Renderer{\n\t\tCtx:       ctx,\n\t\tStatus:    status,\n\t\tComponent: component,\n\t}\n}\n\ntype Renderer struct {\n\tCtx       context.Context\n\tStatus    int\n\tComponent templ.Component\n}\n\nfunc (t Renderer) Render(w http.ResponseWriter) error {\n\tt.WriteContentType(w)\n\tif t.Status != -1 {\n\t\tw.WriteHeader(t.Status)\n\t}\n\tif t.Component != nil {\n\t\treturn t.Component.Render(t.Ctx, w)\n\t}\n\treturn nil\n}\n\nfunc (t Renderer) WriteContentType(w http.ResponseWriter) {\n\tw.Header().Set(\"Content-Type\", \"text/html; charset=utf-8\")\n}\n"
  },
  {
    "path": "examples/integration-gin/go.mod",
    "content": "module github.com/a-h/templ/examples/integration-gin\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.663\n\tgithub.com/gin-gonic/gin v1.11.0\n)\n\nrequire (\n\tgithub.com/bytedance/gopkg v0.1.3 // indirect\n\tgithub.com/bytedance/sonic v1.14.2 // indirect\n\tgithub.com/bytedance/sonic/loader v0.4.0 // indirect\n\tgithub.com/cloudwego/base64x v0.1.6 // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.12 // indirect\n\tgithub.com/gin-contrib/sse v1.1.0 // indirect\n\tgithub.com/go-playground/locales v0.14.1 // indirect\n\tgithub.com/go-playground/universal-translator v0.18.1 // indirect\n\tgithub.com/go-playground/validator/v10 v10.30.1 // indirect\n\tgithub.com/goccy/go-json v0.10.5 // indirect\n\tgithub.com/goccy/go-yaml v1.19.1 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.3.0 // indirect\n\tgithub.com/leodido/go-urn v1.4.0 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.2 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/quic-go/qpack v0.6.0 // indirect\n\tgithub.com/quic-go/quic-go v0.58.0 // indirect\n\tgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirect\n\tgithub.com/ugorji/go/codec v1.3.1 // indirect\n\tgo.uber.org/mock v0.6.0 // indirect\n\tgolang.org/x/arch v0.23.0 // indirect\n\tgolang.org/x/crypto v0.48.0 // indirect\n\tgolang.org/x/net v0.51.0 // indirect\n\tgolang.org/x/sys v0.41.0 // indirect\n\tgolang.org/x/text v0.34.0 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/integration-gin/go.sum",
    "content": "github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=\ngithub.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=\ngithub.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=\ngithub.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=\ngithub.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=\ngithub.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=\ngithub.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=\ngithub.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=\ngithub.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=\ngithub.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=\ngithub.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=\ngithub.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=\ngithub.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=\ngithub.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=\ngithub.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=\ngithub.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=\ngithub.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=\ngithub.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=\ngithub.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=\ngithub.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=\ngithub.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=\ngithub.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/goccy/go-yaml v1.19.1 h1:3rG3+v8pkhRqoQ/88NYNMHYVGYztCOCIZ7UQhu7H+NE=\ngithub.com/goccy/go-yaml v1.19.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=\ngithub.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=\ngithub.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=\ngithub.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=\ngithub.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=\ngithub.com/quic-go/quic-go v0.58.0 h1:ggY2pvZaVdB9EyojxL1p+5mptkuHyX5MOSv4dgWF4Ug=\ngithub.com/quic-go/quic-go v0.58.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=\ngithub.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=\ngithub.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=\ngithub.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=\ngo.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=\ngo.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=\ngolang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg=\ngolang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=\ngolang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=\ngolang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=\ngolang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=\ngolang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=\ngolang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=\ngolang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "examples/integration-gin/home.html",
    "content": "<div>Hello world</div>\n"
  },
  {
    "path": "examples/integration-gin/home.templ",
    "content": "package main\n\ntempl Home() {\n\t<div>Hello world</div>\n}\n"
  },
  {
    "path": "examples/integration-gin/home_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Home() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Hello world</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/integration-gin/main.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/a-h/templ/examples/integration-gin/gintemplrenderer\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc main() {\n\tengine := gin.Default()\n\tengine.LoadHTMLFiles(\"./home.html\")\n\n\t//engine.HTMLRender = gintemplrenderer.Default\n\n\tginHtmlRenderer := engine.HTMLRender\n\tengine.HTMLRender = &gintemplrenderer.HTMLTemplRenderer{FallbackHtmlRenderer: ginHtmlRenderer}\n\n\t// Disable trusted proxy warning.\n\tengine.SetTrustedProxies(nil)\n\n\tengine.GET(\"/\", func(c *gin.Context) {\n\t\tc.HTML(http.StatusOK, \"\", Home())\n\t})\n\n\tengine.GET(\"/with-ctx\", func(c *gin.Context) {\n\t\tr := gintemplrenderer.New(c.Request.Context(), http.StatusOK, Home())\n\t\tc.Render(http.StatusOK, r)\n\t})\n\n\tengine.GET(\"/with-fallback-renderer\", func(c *gin.Context) {\n\t\tc.HTML(http.StatusOK, \"home.html\", gin.H{})\n\t})\n\n\tengine.Run(\":8080\")\n}\n"
  },
  {
    "path": "examples/integration-go-echarts/components.templ",
    "content": "package main\n\nimport \"github.com/go-echarts/go-echarts/v2/charts\"\n\ntempl Home(chart *charts.Bar) {\n\t<html>\n\t\t<head>\n\t\t\t<title>Bar chart</title>\n\t\t</head>\n\t\t<body>\n\t\t\t@ConvertChartToTemplComponent(chart)\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/integration-go-echarts/components_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"github.com/go-echarts/go-echarts/v2/charts\"\n\nfunc Home(chart *charts.Bar) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<html><head><title>Bar chart</title></head><body>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = ConvertChartToTemplComponent(chart).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/integration-go-echarts/go.mod",
    "content": "module github.com/a-h/templ/examples/integration-go-echarts\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.529\n\tgithub.com/go-echarts/go-echarts/v2 v2.4.0\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/integration-go-echarts/go.sum",
    "content": "github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/go-echarts/go-echarts/v2 v2.4.0 h1:efD46dmAvaZEWrBHAGjE8cfDK48vvFTHz5N9VqW5rYc=\ngithub.com/go-echarts/go-echarts/v2 v2.4.0/go.mod h1:56YlvzhW/a+du15f3S2qUGNDfKnFOeJSThBIrVFHDtI=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "examples/integration-go-echarts/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/go-echarts/go-echarts/v2/charts\"\n\t\"github.com/go-echarts/go-echarts/v2/opts\"\n)\n\nfunc generateBarItems() []opts.BarData {\n\titems := make([]opts.BarData, 0)\n\tfor range 7 {\n\t\titems = append(items, opts.BarData{Value: rand.Intn(300)})\n\t}\n\treturn items\n}\n\nfunc createBarChart() *charts.Bar {\n\tbar := charts.NewBar()\n\tbar.SetGlobalOptions(charts.WithTitleOpts(opts.Title{\n\t\tTitle:    \"Bar chart\",\n\t\tSubtitle: \"That works well with templ\",\n\t}))\n\tbar.SetXAxis([]string{\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"}).\n\t\tAddSeries(\"Category A\", generateBarItems()).\n\t\tAddSeries(\"Category B\", generateBarItems())\n\treturn bar\n}\n\n// The charts all have a `Render(w io.Writer) error` method on them.\n// That method is very similar to templ's Render method.\ntype Renderable interface {\n\tRender(w io.Writer) error\n}\n\n// So lets adapt it.\nfunc ConvertChartToTemplComponent(chart Renderable) templ.Component {\n\treturn templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\treturn chart.Render(w)\n\t})\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tchart := createBarChart()\n\t\th := templ.Handler(Home(chart))\n\t\th.ServeHTTP(w, r)\n\t})\n\thttp.ListenAndServe(\"localhost:3000\", nil)\n}\n"
  },
  {
    "path": "examples/integration-gofiber/README.md",
    "content": "## Example\n\nThis example demonstrates the usage of templ with gofiber.\n\nAs soon as you start the server you can access http://localhost:3000/ and see the rendered page.\n\nIf you change the URL to http://localhost:3000/john you will see your parameter printed on the page.\n\nThis happens both through parameter passing into the templ component and through context using fiber locals.\n\n## Tasks\n\n### build-templ\n\n```\ntempl generate\n```\n\n### run\n\n```\ngo run .\n```\n\n"
  },
  {
    "path": "examples/integration-gofiber/go.mod",
    "content": "module github.com/a-h/templ/examples/integration-gofiber\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.747\n\tgithub.com/gofiber/fiber/v3 v3.1.0\n)\n\nrequire (\n\tgithub.com/andybalholm/brotli v1.2.0 // indirect\n\tgithub.com/gofiber/schema v1.7.0 // indirect\n\tgithub.com/gofiber/utils/v2 v2.0.2 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/klauspost/compress v1.18.4 // indirect\n\tgithub.com/mattn/go-colorable v0.1.14 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/philhofer/fwd v1.2.0 // indirect\n\tgithub.com/tinylib/msgp v1.6.3 // indirect\n\tgithub.com/valyala/bytebufferpool v1.0.0 // indirect\n\tgithub.com/valyala/fasthttp v1.69.0 // indirect\n\tgolang.org/x/crypto v0.48.0 // indirect\n\tgolang.org/x/net v0.51.0 // indirect\n\tgolang.org/x/sys v0.41.0 // indirect\n\tgolang.org/x/text v0.34.0 // indirect\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/integration-gofiber/go.sum",
    "content": "github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=\ngithub.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=\ngithub.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=\ngithub.com/gofiber/fiber/v3 v3.1.0 h1:1p4I820pIa+FGxfwWuQZ5rAyX0WlGZbGT6Hnuxt6hKY=\ngithub.com/gofiber/fiber/v3 v3.1.0/go.mod h1:n2nYQovvL9z3Too/FGOfgtERjW3GQcAUqgfoezGBZdU=\ngithub.com/gofiber/schema v1.7.0 h1:yNM+FNRZjyYEli9Ey0AXRBrAY9jTnb+kmGs3lJGPvKg=\ngithub.com/gofiber/schema v1.7.0/go.mod h1:A/X5Ffyru4p9eBdp99qu+nzviHzQiZ7odLT+TwxWhbk=\ngithub.com/gofiber/utils/v2 v2.0.2 h1:ShRRssz0F3AhTlAQcuEj54OEDtWF7+HJDwEi/aa6QLI=\ngithub.com/gofiber/utils/v2 v2.0.2/go.mod h1:+9Ub4NqQ+IaJoTliq5LfdmOJAA/Hzwf4pXOxOa3RrJ0=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=\ngithub.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=\ngithub.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/shamaton/msgpack/v3 v3.1.0 h1:jsk0vEAqVvvS9+fTZ5/EcQ9tz860c9pWxJ4Iwecz8gU=\ngithub.com/shamaton/msgpack/v3 v3.1.0/go.mod h1:DcQG8jrdrQCIxr3HlMYkiXdMhK+KfN2CitkyzsQV4uc=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s=\ngithub.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=\ngithub.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=\ngithub.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=\ngithub.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZyVI=\ngithub.com/valyala/fasthttp v1.69.0/go.mod h1:4wA4PfAraPlAsJ5jMSqCE2ug5tqUPwKXxVj8oNECGcw=\ngithub.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=\ngithub.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=\ngithub.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=\ngithub.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=\ngolang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=\ngolang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=\ngolang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=\ngolang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=\ngolang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=\ngolang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "examples/integration-gofiber/home.templ",
    "content": "package main\n\nimport \"context\"\n\nfunc NameFromContext(ctx context.Context) string {\n\tif name, ok := ctx.Value(\"name\").(string); ok && name != \"\" {\n\t\treturn name\n\t}\n\treturn \"World\"\n}\n\ntempl Home(name string) {\n\t<div>Hello { name }</div>\n\t<div>Hello { NameFromContext(ctx) } (from context)</div>\n}\n\ntempl NotFound() {\n\t<div>404</div>\n}\n"
  },
  {
    "path": "examples/integration-gofiber/home_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"context\"\n\nfunc NameFromContext(ctx context.Context) string {\n\tif name, ok := ctx.Value(\"name\").(string); ok && name != \"\" {\n\t\treturn name\n\t}\n\treturn \"World\"\n}\n\nfunc Home(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Hello \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/integration-gofiber/home.templ`, Line: 13, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div><div>Hello \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(NameFromContext(ctx))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/integration-gofiber/home.templ`, Line: 14, Col: 34}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \" (from context)</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc NotFound() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<div>404</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/integration-gofiber/main.go",
    "content": "package main\n\nimport (\n\t\"github.com/a-h/templ\"\n\t\"github.com/gofiber/fiber/v3\"\n\t\"github.com/gofiber/fiber/v3/log\"\n)\n\nfunc main() {\n\tapp := fiber.New()\n\n\tapp.Get(\"/:name?\", func(c fiber.Ctx) error {\n\t\tname := c.Params(\"name\")\n\t\tc.Locals(\"name\", name)\n\t\tif name == \"\" {\n\t\t\tname = \"World\"\n\t\t}\n\t\treturn Render(c, Home(name))\n\t})\n\tapp.Use(NotFoundMiddleware)\n\n\tlog.Fatal(app.Listen(\":3000\"))\n}\n\nfunc NotFoundMiddleware(c fiber.Ctx) error {\n\tc.Status(fiber.StatusNotFound)\n\treturn Render(c, NotFound())\n}\n\nfunc Render(c fiber.Ctx, component templ.Component) error {\n\tc.Set(\"Content-Type\", \"text/html\")\n\treturn component.Render(c.Context(), c.Response().BodyWriter())\n}\n"
  },
  {
    "path": "examples/integration-react/README.md",
    "content": "## Tasks\n\n### build-templ\n\n```\ntempl generate\n```\n\n### build-js\n\nDir: react\n\n```\nesbuild --bundle index.ts --outdir=../static --minify --global-name=bundle\n```\n\n### run\n\n```\ngo run .\n```\n\n### all\n\nRequires: build-templ\nRequires: build-js\nRequires: run\n\n```\necho \"Running\"\n```\n"
  },
  {
    "path": "examples/integration-react/components.templ",
    "content": "package main\n\ntempl Hello(name string) {\n\t<div data-name={ name }>\n\t\t<script>\n\t\t\t// Place the React component into the parent div.\n\t\t\tbundle.renderHello(document.currentScript.closest(\"div\"));\n\t\t</script>\n\t</div>\n}\n\ntempl page() {\n\t<html>\n\t\t<head>\n\t\t\t<title>React integration</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<div id=\"react-header\"></div>\n\t\t\t<div id=\"react-content\"></div>\n\t\t\t<div>\n\t\t\t\tThis is server-side content from templ.\n\t\t\t</div>\n\t\t\t<!-- Load the React bundle that was created using esbuild -->\n\t\t\t<!-- Since the bundle was coded to expect the react-header and react-content elements to exist already, in this case, the script has to be loaded after the elements are on the page -->\n\t\t\t<script src=\"static/index.js\"></script>\n\t\t\t<!-- Now that the React bundle is loaded, we can use the functions that are in it -->\n\t\t\t<!-- the renderName function in the bundle can be used, but we want to pass it some server-side data -->\n\t\t\tfor _, name := range []string{\"Alice\", \"Bob\", \"Charlie\"} {\n\t\t\t\t@Hello(name)\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/integration-react/components_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Hello(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div data-name=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/integration-react/components.templ`, Line: 4, Col: 22}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\"><script>\\n\\t\\t\\t// Place the React component into the parent div.\\n\\t\\t\\tbundle.renderHello(document.currentScript.closest(\\\"div\\\"));\\n\\t\\t</script></div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc page() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<html><head><title>React integration</title></head><body><div id=\\\"react-header\\\"></div><div id=\\\"react-content\\\"></div><div>This is server-side content from templ.</div><!-- Load the React bundle that was created using esbuild --><!-- Since the bundle was coded to expect the react-header and react-content elements to exist already, in this case, the script has to be loaded after the elements are on the page --><script src=\\\"static/index.js\\\"></script><!-- Now that the React bundle is loaded, we can use the functions that are in it --><!-- the renderName function in the bundle can be used, but we want to pass it some server-side data -->\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor _, name := range []string{\"Alice\", \"Bob\", \"Charlie\"} {\n\t\t\ttempl_7745c5c3_Err = Hello(name).Render(ctx, templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/integration-react/flake.nix",
    "content": "{\n  inputs = {\n    nixpkgs.url = \"github:NixOS/nixpkgs/23.11\";\n  };\n\n  # Flake outputs\n  outputs = { self, nixpkgs }:\n    let\n      # Systems supported\n      allSystems = [\n        \"x86_64-linux\" # 64-bit Intel/AMD Linux\n        \"aarch64-linux\" # 64-bit ARM Linux\n        \"x86_64-darwin\" # 64-bit Intel macOS\n        \"aarch64-darwin\" # 64-bit ARM macOS\n      ];\n\n      # Helper to provide system-specific attributes\n      forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {\n        pkgs = import nixpkgs { inherit system; };\n      });\n    in\n    {\n      # Development environment output\n      devShells = forAllSystems ({ pkgs }: {\n        default = pkgs.mkShell {\n          # The Nix packages provided in the environment\n          packages = with pkgs; [\n            nodejs_18 # Node.js 18, plus npm, npx, and corepack\n            esbuild\n          ];\n        };\n      });\n    };\n}\n"
  },
  {
    "path": "examples/integration-react/go.mod",
    "content": "module github.com/a-h/templ/examples/integration-react\n\ngo 1.25.0\n\nrequire github.com/a-h/templ v0.2.513\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/integration-react/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/integration-react/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\tmux := http.NewServeMux()\n\n\t// Serve the templ page.\n\tmux.Handle(\"/\", templ.Handler(page()))\n\n\t// Serve static content.\n\tmux.Handle(\"/static/\", http.StripPrefix(\"/static/\", http.FileServer(http.Dir(\"static\"))))\n\n\t// Start the server.\n\tfmt.Println(\"listening on localhost:8080\")\n\tif err := http.ListenAndServe(\"localhost:8080\", mux); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "examples/integration-react/react/.gitignore",
    "content": "node_modules\n"
  },
  {
    "path": "examples/integration-react/react/components.tsx",
    "content": "import React from \"react\";\n\nexport const Header = () => (<h1>React component Header</h1>);\n\nexport const Body = () => (<div>This is client-side content from React</div>);\n\nexport const Hello = (name: string) => (<div>Hello {name} (Client-side React, rendering server-side data)</div>);\n"
  },
  {
    "path": "examples/integration-react/react/index.ts",
    "content": "import { createRoot } from 'react-dom/client';\nimport { Header, Body, Hello } from './components';\n\n// Render the React component into the templ page at the react-header.\nconst headerRoot = document.getElementById('react-header');\nif (!headerRoot) {\n\tthrow new Error('Could not find element with id react-header');\n}\nconst headerReactRoot = createRoot(headerRoot);\nheaderReactRoot.render(Header());\n\n// Add the body React component.\nconst contentRoot = document.getElementById('react-content');\nif (!contentRoot) {\n\tthrow new Error('Could not find element with id react-content');\n}\nconst contentReactRoot = createRoot(contentRoot);\ncontentReactRoot.render(Body());\n\n// Provide a helper for rendering hello.\nexport function renderHello(e: HTMLElement) {\n\tconst name = e.getAttribute('data-name') ?? \"\";\n\tcreateRoot(e).render(Hello(name));\n}\n"
  },
  {
    "path": "examples/integration-react/react/package.json",
    "content": "{\n  \"name\": \"integration-react\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.ts\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\"\n  },\n  \"devDependencies\": {\n    \"@types/react-dom\": \"^18.2.18\",\n    \"typescript\": \"^5.3.3\"\n  }\n}\n"
  },
  {
    "path": "examples/integration-react/react/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\"\n  }\n}\n"
  },
  {
    "path": "examples/integration-react/static/index.js",
    "content": "var bundle=(()=>{var Ac=Object.create;var nr=Object.defineProperty;var Hc=Object.getOwnPropertyDescriptor;var Bc=Object.getOwnPropertyNames;var Wc=Object.getPrototypeOf,$c=Object.prototype.hasOwnProperty;var je=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports),Qc=(e,n)=>{for(var t in n)nr(e,t,{get:n[t],enumerable:!0})},Gu=(e,n,t,r)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let l of Bc(n))!$c.call(e,l)&&l!==t&&nr(e,l,{get:()=>n[l],enumerable:!(r=Hc(n,l))||r.enumerable});return e};var Nl=(e,n,t)=>(t=e!=null?Ac(Wc(e)):{},Gu(n||!e||!e.__esModule?nr(t,\"default\",{value:e,enumerable:!0}):t,e)),Kc=e=>Gu(nr({},\"__esModule\",{value:!0}),e);var ui=je(N=>{\"use strict\";var st=Symbol.for(\"react.element\"),Yc=Symbol.for(\"react.portal\"),Xc=Symbol.for(\"react.fragment\"),Gc=Symbol.for(\"react.strict_mode\"),Zc=Symbol.for(\"react.profiler\"),Jc=Symbol.for(\"react.provider\"),qc=Symbol.for(\"react.context\"),bc=Symbol.for(\"react.forward_ref\"),ef=Symbol.for(\"react.suspense\"),nf=Symbol.for(\"react.memo\"),tf=Symbol.for(\"react.lazy\"),Zu=Symbol.iterator;function rf(e){return e===null||typeof e!=\"object\"?null:(e=Zu&&e[Zu]||e[\"@@iterator\"],typeof e==\"function\"?e:null)}var bu={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},ei=Object.assign,ni={};function On(e,n,t){this.props=e,this.context=n,this.refs=ni,this.updater=t||bu}On.prototype.isReactComponent={};On.prototype.setState=function(e,n){if(typeof e!=\"object\"&&typeof e!=\"function\"&&e!=null)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,e,n,\"setState\")};On.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,\"forceUpdate\")};function ti(){}ti.prototype=On.prototype;function zl(e,n,t){this.props=e,this.context=n,this.refs=ni,this.updater=t||bu}var Tl=zl.prototype=new ti;Tl.constructor=zl;ei(Tl,On.prototype);Tl.isPureReactComponent=!0;var Ju=Array.isArray,ri=Object.prototype.hasOwnProperty,Ll={current:null},li={key:!0,ref:!0,__self:!0,__source:!0};function oi(e,n,t){var r,l={},o=null,u=null;if(n!=null)for(r in n.ref!==void 0&&(u=n.ref),n.key!==void 0&&(o=\"\"+n.key),n)ri.call(n,r)&&!li.hasOwnProperty(r)&&(l[r]=n[r]);var i=arguments.length-2;if(i===1)l.children=t;else if(1<i){for(var s=Array(i),f=0;f<i;f++)s[f]=arguments[f+2];l.children=s}if(e&&e.defaultProps)for(r in i=e.defaultProps,i)l[r]===void 0&&(l[r]=i[r]);return{$$typeof:st,type:e,key:o,ref:u,props:l,_owner:Ll.current}}function lf(e,n){return{$$typeof:st,type:e.type,key:n,ref:e.ref,props:e.props,_owner:e._owner}}function Rl(e){return typeof e==\"object\"&&e!==null&&e.$$typeof===st}function of(e){var n={\"=\":\"=0\",\":\":\"=2\"};return\"$\"+e.replace(/[=:]/g,function(t){return n[t]})}var qu=/\\/+/g;function Pl(e,n){return typeof e==\"object\"&&e!==null&&e.key!=null?of(\"\"+e.key):n.toString(36)}function rr(e,n,t,r,l){var o=typeof e;(o===\"undefined\"||o===\"boolean\")&&(e=null);var u=!1;if(e===null)u=!0;else switch(o){case\"string\":case\"number\":u=!0;break;case\"object\":switch(e.$$typeof){case st:case Yc:u=!0}}if(u)return u=e,l=l(u),e=r===\"\"?\".\"+Pl(u,0):r,Ju(l)?(t=\"\",e!=null&&(t=e.replace(qu,\"$&/\")+\"/\"),rr(l,n,t,\"\",function(f){return f})):l!=null&&(Rl(l)&&(l=lf(l,t+(!l.key||u&&u.key===l.key?\"\":(\"\"+l.key).replace(qu,\"$&/\")+\"/\")+e)),n.push(l)),1;if(u=0,r=r===\"\"?\".\":r+\":\",Ju(e))for(var i=0;i<e.length;i++){o=e[i];var s=r+Pl(o,i);u+=rr(o,n,t,s,l)}else if(s=rf(e),typeof s==\"function\")for(e=s.call(e),i=0;!(o=e.next()).done;)o=o.value,s=r+Pl(o,i++),u+=rr(o,n,t,s,l);else if(o===\"object\")throw n=String(e),Error(\"Objects are not valid as a React child (found: \"+(n===\"[object Object]\"?\"object with keys {\"+Object.keys(e).join(\", \")+\"}\":n)+\"). If you meant to render a collection of children, use an array instead.\");return u}function tr(e,n,t){if(e==null)return e;var r=[],l=0;return rr(e,r,\"\",\"\",function(o){return n.call(t,o,l++)}),r}function uf(e){if(e._status===-1){var n=e._result;n=n(),n.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t)},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t)}),e._status===-1&&(e._status=0,e._result=n)}if(e._status===1)return e._result.default;throw e._result}var ne={current:null},lr={transition:null},sf={ReactCurrentDispatcher:ne,ReactCurrentBatchConfig:lr,ReactCurrentOwner:Ll};N.Children={map:tr,forEach:function(e,n,t){tr(e,function(){n.apply(this,arguments)},t)},count:function(e){var n=0;return tr(e,function(){n++}),n},toArray:function(e){return tr(e,function(n){return n})||[]},only:function(e){if(!Rl(e))throw Error(\"React.Children.only expected to receive a single React element child.\");return e}};N.Component=On;N.Fragment=Xc;N.Profiler=Zc;N.PureComponent=zl;N.StrictMode=Gc;N.Suspense=ef;N.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=sf;N.cloneElement=function(e,n,t){if(e==null)throw Error(\"React.cloneElement(...): The argument must be a React element, but you passed \"+e+\".\");var r=ei({},e.props),l=e.key,o=e.ref,u=e._owner;if(n!=null){if(n.ref!==void 0&&(o=n.ref,u=Ll.current),n.key!==void 0&&(l=\"\"+n.key),e.type&&e.type.defaultProps)var i=e.type.defaultProps;for(s in n)ri.call(n,s)&&!li.hasOwnProperty(s)&&(r[s]=n[s]===void 0&&i!==void 0?i[s]:n[s])}var s=arguments.length-2;if(s===1)r.children=t;else if(1<s){i=Array(s);for(var f=0;f<s;f++)i[f]=arguments[f+2];r.children=i}return{$$typeof:st,type:e.type,key:l,ref:o,props:r,_owner:u}};N.createContext=function(e){return e={$$typeof:qc,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},e.Provider={$$typeof:Jc,_context:e},e.Consumer=e};N.createElement=oi;N.createFactory=function(e){var n=oi.bind(null,e);return n.type=e,n};N.createRef=function(){return{current:null}};N.forwardRef=function(e){return{$$typeof:bc,render:e}};N.isValidElement=Rl;N.lazy=function(e){return{$$typeof:tf,_payload:{_status:-1,_result:e},_init:uf}};N.memo=function(e,n){return{$$typeof:nf,type:e,compare:n===void 0?null:n}};N.startTransition=function(e){var n=lr.transition;lr.transition={};try{e()}finally{lr.transition=n}};N.unstable_act=function(){throw Error(\"act(...) is not supported in production builds of React.\")};N.useCallback=function(e,n){return ne.current.useCallback(e,n)};N.useContext=function(e){return ne.current.useContext(e)};N.useDebugValue=function(){};N.useDeferredValue=function(e){return ne.current.useDeferredValue(e)};N.useEffect=function(e,n){return ne.current.useEffect(e,n)};N.useId=function(){return ne.current.useId()};N.useImperativeHandle=function(e,n,t){return ne.current.useImperativeHandle(e,n,t)};N.useInsertionEffect=function(e,n){return ne.current.useInsertionEffect(e,n)};N.useLayoutEffect=function(e,n){return ne.current.useLayoutEffect(e,n)};N.useMemo=function(e,n){return ne.current.useMemo(e,n)};N.useReducer=function(e,n,t){return ne.current.useReducer(e,n,t)};N.useRef=function(e){return ne.current.useRef(e)};N.useState=function(e){return ne.current.useState(e)};N.useSyncExternalStore=function(e,n,t){return ne.current.useSyncExternalStore(e,n,t)};N.useTransition=function(){return ne.current.useTransition()};N.version=\"18.2.0\"});var Ol=je((Ep,ii)=>{\"use strict\";ii.exports=ui()});var yi=je(L=>{\"use strict\";function Fl(e,n){var t=e.length;e.push(n);e:for(;0<t;){var r=t-1>>>1,l=e[r];if(0<or(l,n))e[r]=n,e[t]=l,t=r;else break e}}function _e(e){return e.length===0?null:e[0]}function ir(e){if(e.length===0)return null;var n=e[0],t=e.pop();if(t!==n){e[0]=t;e:for(var r=0,l=e.length,o=l>>>1;r<o;){var u=2*(r+1)-1,i=e[u],s=u+1,f=e[s];if(0>or(i,t))s<l&&0>or(f,i)?(e[r]=f,e[s]=t,r=s):(e[r]=i,e[u]=t,r=u);else if(s<l&&0>or(f,t))e[r]=f,e[s]=t,r=s;else break e}}return n}function or(e,n){var t=e.sortIndex-n.sortIndex;return t!==0?t:e.id-n.id}typeof performance==\"object\"&&typeof performance.now==\"function\"?(si=performance,L.unstable_now=function(){return si.now()}):(Dl=Date,ai=Dl.now(),L.unstable_now=function(){return Dl.now()-ai});var si,Dl,ai,Re=[],Ge=[],af=1,he=null,Z=3,sr=!1,yn=!1,ct=!1,di=typeof setTimeout==\"function\"?setTimeout:null,pi=typeof clearTimeout==\"function\"?clearTimeout:null,ci=typeof setImmediate<\"u\"?setImmediate:null;typeof navigator<\"u\"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function jl(e){for(var n=_e(Ge);n!==null;){if(n.callback===null)ir(Ge);else if(n.startTime<=e)ir(Ge),n.sortIndex=n.expirationTime,Fl(Re,n);else break;n=_e(Ge)}}function Ul(e){if(ct=!1,jl(e),!yn)if(_e(Re)!==null)yn=!0,Al(Vl);else{var n=_e(Ge);n!==null&&Hl(Ul,n.startTime-e)}}function Vl(e,n){yn=!1,ct&&(ct=!1,pi(ft),ft=-1),sr=!0;var t=Z;try{for(jl(n),he=_e(Re);he!==null&&(!(he.expirationTime>n)||e&&!hi());){var r=he.callback;if(typeof r==\"function\"){he.callback=null,Z=he.priorityLevel;var l=r(he.expirationTime<=n);n=L.unstable_now(),typeof l==\"function\"?he.callback=l:he===_e(Re)&&ir(Re),jl(n)}else ir(Re);he=_e(Re)}if(he!==null)var o=!0;else{var u=_e(Ge);u!==null&&Hl(Ul,u.startTime-n),o=!1}return o}finally{he=null,Z=t,sr=!1}}var ar=!1,ur=null,ft=-1,mi=5,vi=-1;function hi(){return!(L.unstable_now()-vi<mi)}function Ml(){if(ur!==null){var e=L.unstable_now();vi=e;var n=!0;try{n=ur(!0,e)}finally{n?at():(ar=!1,ur=null)}}else ar=!1}var at;typeof ci==\"function\"?at=function(){ci(Ml)}:typeof MessageChannel<\"u\"?(Il=new MessageChannel,fi=Il.port2,Il.port1.onmessage=Ml,at=function(){fi.postMessage(null)}):at=function(){di(Ml,0)};var Il,fi;function Al(e){ur=e,ar||(ar=!0,at())}function Hl(e,n){ft=di(function(){e(L.unstable_now())},n)}L.unstable_IdlePriority=5;L.unstable_ImmediatePriority=1;L.unstable_LowPriority=4;L.unstable_NormalPriority=3;L.unstable_Profiling=null;L.unstable_UserBlockingPriority=2;L.unstable_cancelCallback=function(e){e.callback=null};L.unstable_continueExecution=function(){yn||sr||(yn=!0,Al(Vl))};L.unstable_forceFrameRate=function(e){0>e||125<e?console.error(\"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported\"):mi=0<e?Math.floor(1e3/e):5};L.unstable_getCurrentPriorityLevel=function(){return Z};L.unstable_getFirstCallbackNode=function(){return _e(Re)};L.unstable_next=function(e){switch(Z){case 1:case 2:case 3:var n=3;break;default:n=Z}var t=Z;Z=n;try{return e()}finally{Z=t}};L.unstable_pauseExecution=function(){};L.unstable_requestPaint=function(){};L.unstable_runWithPriority=function(e,n){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var t=Z;Z=e;try{return n()}finally{Z=t}};L.unstable_scheduleCallback=function(e,n,t){var r=L.unstable_now();switch(typeof t==\"object\"&&t!==null?(t=t.delay,t=typeof t==\"number\"&&0<t?r+t:r):t=r,e){case 1:var l=-1;break;case 2:l=250;break;case 5:l=1073741823;break;case 4:l=1e4;break;default:l=5e3}return l=t+l,e={id:af++,callback:n,priorityLevel:e,startTime:t,expirationTime:l,sortIndex:-1},t>r?(e.sortIndex=t,Fl(Ge,e),_e(Re)===null&&e===_e(Ge)&&(ct?(pi(ft),ft=-1):ct=!0,Hl(Ul,t-r))):(e.sortIndex=l,Fl(Re,e),yn||sr||(yn=!0,Al(Vl))),e};L.unstable_shouldYield=hi;L.unstable_wrapCallback=function(e){var n=Z;return function(){var t=Z;Z=n;try{return e.apply(this,arguments)}finally{Z=t}}}});var wi=je((Cp,gi)=>{\"use strict\";gi.exports=yi()});var xc=je(ve=>{\"use strict\";var Ns=Ol(),pe=wi();function h(e){for(var n=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+e,t=1;t<arguments.length;t++)n+=\"&args[]=\"+encodeURIComponent(arguments[t]);return\"Minified React error #\"+e+\"; visit \"+n+\" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"}var Ps=new Set,Dt={};function Ln(e,n){bn(e,n),bn(e+\"Capture\",n)}function bn(e,n){for(Dt[e]=n,e=0;e<n.length;e++)Ps.add(n[e])}var We=!(typeof window>\"u\"||typeof window.document>\"u\"||typeof window.document.createElement>\"u\"),co=Object.prototype.hasOwnProperty,cf=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,Si={},ki={};function ff(e){return co.call(ki,e)?!0:co.call(Si,e)?!1:cf.test(e)?ki[e]=!0:(Si[e]=!0,!1)}function df(e,n,t,r){if(t!==null&&t.type===0)return!1;switch(typeof n){case\"function\":case\"symbol\":return!0;case\"boolean\":return r?!1:t!==null?!t.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!==\"data-\"&&e!==\"aria-\");default:return!1}}function pf(e,n,t,r){if(n===null||typeof n>\"u\"||df(e,n,t,r))return!0;if(r)return!1;if(t!==null)switch(t.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function le(e,n,t,r,l,o,u){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=r,this.attributeNamespace=l,this.mustUseProperty=t,this.propertyName=e,this.type=n,this.sanitizeURL=o,this.removeEmptyString=u}var G={};\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach(function(e){G[e]=new le(e,0,!1,e,null,!1,!1)});[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach(function(e){var n=e[0];G[n]=new le(n,1,!1,e[1],null,!1,!1)});[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach(function(e){G[e]=new le(e,2,!1,e.toLowerCase(),null,!1,!1)});[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach(function(e){G[e]=new le(e,2,!1,e,null,!1,!1)});\"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope\".split(\" \").forEach(function(e){G[e]=new le(e,3,!1,e.toLowerCase(),null,!1,!1)});[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach(function(e){G[e]=new le(e,3,!0,e,null,!1,!1)});[\"capture\",\"download\"].forEach(function(e){G[e]=new le(e,4,!1,e,null,!1,!1)});[\"cols\",\"rows\",\"size\",\"span\"].forEach(function(e){G[e]=new le(e,6,!1,e,null,!1,!1)});[\"rowSpan\",\"start\"].forEach(function(e){G[e]=new le(e,5,!1,e.toLowerCase(),null,!1,!1)});var ru=/[\\-:]([a-z])/g;function lu(e){return e[1].toUpperCase()}\"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height\".split(\" \").forEach(function(e){var n=e.replace(ru,lu);G[n]=new le(n,1,!1,e,null,!1,!1)});\"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach(function(e){var n=e.replace(ru,lu);G[n]=new le(n,1,!1,e,\"http://www.w3.org/1999/xlink\",!1,!1)});[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach(function(e){var n=e.replace(ru,lu);G[n]=new le(n,1,!1,e,\"http://www.w3.org/XML/1998/namespace\",!1,!1)});[\"tabIndex\",\"crossOrigin\"].forEach(function(e){G[e]=new le(e,1,!1,e.toLowerCase(),null,!1,!1)});G.xlinkHref=new le(\"xlinkHref\",1,!1,\"xlink:href\",\"http://www.w3.org/1999/xlink\",!0,!1);[\"src\",\"href\",\"action\",\"formAction\"].forEach(function(e){G[e]=new le(e,1,!1,e.toLowerCase(),null,!0,!0)});function ou(e,n,t,r){var l=G.hasOwnProperty(n)?G[n]:null;(l!==null?l.type!==0:r||!(2<n.length)||n[0]!==\"o\"&&n[0]!==\"O\"||n[1]!==\"n\"&&n[1]!==\"N\")&&(pf(n,t,l,r)&&(t=null),r||l===null?ff(n)&&(t===null?e.removeAttribute(n):e.setAttribute(n,\"\"+t)):l.mustUseProperty?e[l.propertyName]=t===null?l.type===3?!1:\"\":t:(n=l.attributeName,r=l.attributeNamespace,t===null?e.removeAttribute(n):(l=l.type,t=l===3||l===4&&t===!0?\"\":\"\"+t,r?e.setAttributeNS(r,n,t):e.setAttribute(n,t))))}var Ye=Ns.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,cr=Symbol.for(\"react.element\"),In=Symbol.for(\"react.portal\"),Fn=Symbol.for(\"react.fragment\"),uu=Symbol.for(\"react.strict_mode\"),fo=Symbol.for(\"react.profiler\"),zs=Symbol.for(\"react.provider\"),Ts=Symbol.for(\"react.context\"),iu=Symbol.for(\"react.forward_ref\"),po=Symbol.for(\"react.suspense\"),mo=Symbol.for(\"react.suspense_list\"),su=Symbol.for(\"react.memo\"),Je=Symbol.for(\"react.lazy\");Symbol.for(\"react.scope\");Symbol.for(\"react.debug_trace_mode\");var Ls=Symbol.for(\"react.offscreen\");Symbol.for(\"react.legacy_hidden\");Symbol.for(\"react.cache\");Symbol.for(\"react.tracing_marker\");var Ei=Symbol.iterator;function dt(e){return e===null||typeof e!=\"object\"?null:(e=Ei&&e[Ei]||e[\"@@iterator\"],typeof e==\"function\"?e:null)}var j=Object.assign,Bl;function St(e){if(Bl===void 0)try{throw Error()}catch(t){var n=t.stack.trim().match(/\\n( *(at )?)/);Bl=n&&n[1]||\"\"}return`\n`+Bl+e}var Wl=!1;function $l(e,n){if(!e||Wl)return\"\";Wl=!0;var t=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(n)if(n=function(){throw Error()},Object.defineProperty(n.prototype,\"props\",{set:function(){throw Error()}}),typeof Reflect==\"object\"&&Reflect.construct){try{Reflect.construct(n,[])}catch(f){var r=f}Reflect.construct(e,[],n)}else{try{n.call()}catch(f){r=f}e.call(n.prototype)}else{try{throw Error()}catch(f){r=f}e()}}catch(f){if(f&&r&&typeof f.stack==\"string\"){for(var l=f.stack.split(`\n`),o=r.stack.split(`\n`),u=l.length-1,i=o.length-1;1<=u&&0<=i&&l[u]!==o[i];)i--;for(;1<=u&&0<=i;u--,i--)if(l[u]!==o[i]){if(u!==1||i!==1)do if(u--,i--,0>i||l[u]!==o[i]){var s=`\n`+l[u].replace(\" at new \",\" at \");return e.displayName&&s.includes(\"<anonymous>\")&&(s=s.replace(\"<anonymous>\",e.displayName)),s}while(1<=u&&0<=i);break}}}finally{Wl=!1,Error.prepareStackTrace=t}return(e=e?e.displayName||e.name:\"\")?St(e):\"\"}function mf(e){switch(e.tag){case 5:return St(e.type);case 16:return St(\"Lazy\");case 13:return St(\"Suspense\");case 19:return St(\"SuspenseList\");case 0:case 2:case 15:return e=$l(e.type,!1),e;case 11:return e=$l(e.type.render,!1),e;case 1:return e=$l(e.type,!0),e;default:return\"\"}}function vo(e){if(e==null)return null;if(typeof e==\"function\")return e.displayName||e.name||null;if(typeof e==\"string\")return e;switch(e){case Fn:return\"Fragment\";case In:return\"Portal\";case fo:return\"Profiler\";case uu:return\"StrictMode\";case po:return\"Suspense\";case mo:return\"SuspenseList\"}if(typeof e==\"object\")switch(e.$$typeof){case Ts:return(e.displayName||\"Context\")+\".Consumer\";case zs:return(e._context.displayName||\"Context\")+\".Provider\";case iu:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||\"\",e=e!==\"\"?\"ForwardRef(\"+e+\")\":\"ForwardRef\"),e;case su:return n=e.displayName||null,n!==null?n:vo(e.type)||\"Memo\";case Je:n=e._payload,e=e._init;try{return vo(e(n))}catch{}}return null}function vf(e){var n=e.type;switch(e.tag){case 24:return\"Cache\";case 9:return(n.displayName||\"Context\")+\".Consumer\";case 10:return(n._context.displayName||\"Context\")+\".Provider\";case 18:return\"DehydratedFragment\";case 11:return e=n.render,e=e.displayName||e.name||\"\",n.displayName||(e!==\"\"?\"ForwardRef(\"+e+\")\":\"ForwardRef\");case 7:return\"Fragment\";case 5:return n;case 4:return\"Portal\";case 3:return\"Root\";case 6:return\"Text\";case 16:return vo(n);case 8:return n===uu?\"StrictMode\":\"Mode\";case 22:return\"Offscreen\";case 12:return\"Profiler\";case 21:return\"Scope\";case 13:return\"Suspense\";case 19:return\"SuspenseList\";case 25:return\"TracingMarker\";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n==\"function\")return n.displayName||n.name||null;if(typeof n==\"string\")return n}return null}function dn(e){switch(typeof e){case\"boolean\":case\"number\":case\"string\":case\"undefined\":return e;case\"object\":return e;default:return\"\"}}function Rs(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()===\"input\"&&(n===\"checkbox\"||n===\"radio\")}function hf(e){var n=Rs(e)?\"checked\":\"value\",t=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),r=\"\"+e[n];if(!e.hasOwnProperty(n)&&typeof t<\"u\"&&typeof t.get==\"function\"&&typeof t.set==\"function\"){var l=t.get,o=t.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return l.call(this)},set:function(u){r=\"\"+u,o.call(this,u)}}),Object.defineProperty(e,n,{enumerable:t.enumerable}),{getValue:function(){return r},setValue:function(u){r=\"\"+u},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function fr(e){e._valueTracker||(e._valueTracker=hf(e))}function Os(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var t=n.getValue(),r=\"\";return e&&(r=Rs(e)?e.checked?\"true\":\"false\":e.value),e=r,e!==t?(n.setValue(e),!0):!1}function Vr(e){if(e=e||(typeof document<\"u\"?document:void 0),typeof e>\"u\")return null;try{return e.activeElement||e.body}catch{return e.body}}function ho(e,n){var t=n.checked;return j({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:t??e._wrapperState.initialChecked})}function _i(e,n){var t=n.defaultValue==null?\"\":n.defaultValue,r=n.checked!=null?n.checked:n.defaultChecked;t=dn(n.value!=null?n.value:t),e._wrapperState={initialChecked:r,initialValue:t,controlled:n.type===\"checkbox\"||n.type===\"radio\"?n.checked!=null:n.value!=null}}function Ds(e,n){n=n.checked,n!=null&&ou(e,\"checked\",n,!1)}function yo(e,n){Ds(e,n);var t=dn(n.value),r=n.type;if(t!=null)r===\"number\"?(t===0&&e.value===\"\"||e.value!=t)&&(e.value=\"\"+t):e.value!==\"\"+t&&(e.value=\"\"+t);else if(r===\"submit\"||r===\"reset\"){e.removeAttribute(\"value\");return}n.hasOwnProperty(\"value\")?go(e,n.type,t):n.hasOwnProperty(\"defaultValue\")&&go(e,n.type,dn(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function Ci(e,n,t){if(n.hasOwnProperty(\"value\")||n.hasOwnProperty(\"defaultValue\")){var r=n.type;if(!(r!==\"submit\"&&r!==\"reset\"||n.value!==void 0&&n.value!==null))return;n=\"\"+e._wrapperState.initialValue,t||n===e.value||(e.value=n),e.defaultValue=n}t=e.name,t!==\"\"&&(e.name=\"\"),e.defaultChecked=!!e._wrapperState.initialChecked,t!==\"\"&&(e.name=t)}function go(e,n,t){(n!==\"number\"||Vr(e.ownerDocument)!==e)&&(t==null?e.defaultValue=\"\"+e._wrapperState.initialValue:e.defaultValue!==\"\"+t&&(e.defaultValue=\"\"+t))}var kt=Array.isArray;function Yn(e,n,t,r){if(e=e.options,n){n={};for(var l=0;l<t.length;l++)n[\"$\"+t[l]]=!0;for(t=0;t<e.length;t++)l=n.hasOwnProperty(\"$\"+e[t].value),e[t].selected!==l&&(e[t].selected=l),l&&r&&(e[t].defaultSelected=!0)}else{for(t=\"\"+dn(t),n=null,l=0;l<e.length;l++){if(e[l].value===t){e[l].selected=!0,r&&(e[l].defaultSelected=!0);return}n!==null||e[l].disabled||(n=e[l])}n!==null&&(n.selected=!0)}}function wo(e,n){if(n.dangerouslySetInnerHTML!=null)throw Error(h(91));return j({},n,{value:void 0,defaultValue:void 0,children:\"\"+e._wrapperState.initialValue})}function xi(e,n){var t=n.value;if(t==null){if(t=n.children,n=n.defaultValue,t!=null){if(n!=null)throw Error(h(92));if(kt(t)){if(1<t.length)throw Error(h(93));t=t[0]}n=t}n==null&&(n=\"\"),t=n}e._wrapperState={initialValue:dn(t)}}function Ms(e,n){var t=dn(n.value),r=dn(n.defaultValue);t!=null&&(t=\"\"+t,t!==e.value&&(e.value=t),n.defaultValue==null&&e.defaultValue!==t&&(e.defaultValue=t)),r!=null&&(e.defaultValue=\"\"+r)}function Ni(e){var n=e.textContent;n===e._wrapperState.initialValue&&n!==\"\"&&n!==null&&(e.value=n)}function Is(e){switch(e){case\"svg\":return\"http://www.w3.org/2000/svg\";case\"math\":return\"http://www.w3.org/1998/Math/MathML\";default:return\"http://www.w3.org/1999/xhtml\"}}function So(e,n){return e==null||e===\"http://www.w3.org/1999/xhtml\"?Is(n):e===\"http://www.w3.org/2000/svg\"&&n===\"foreignObject\"?\"http://www.w3.org/1999/xhtml\":e}var dr,Fs=function(e){return typeof MSApp<\"u\"&&MSApp.execUnsafeLocalFunction?function(n,t,r,l){MSApp.execUnsafeLocalFunction(function(){return e(n,t,r,l)})}:e}(function(e,n){if(e.namespaceURI!==\"http://www.w3.org/2000/svg\"||\"innerHTML\"in e)e.innerHTML=n;else{for(dr=dr||document.createElement(\"div\"),dr.innerHTML=\"<svg>\"+n.valueOf().toString()+\"</svg>\",n=dr.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function Mt(e,n){if(n){var t=e.firstChild;if(t&&t===e.lastChild&&t.nodeType===3){t.nodeValue=n;return}}e.textContent=n}var Ct={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},yf=[\"Webkit\",\"ms\",\"Moz\",\"O\"];Object.keys(Ct).forEach(function(e){yf.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),Ct[n]=Ct[e]})});function js(e,n,t){return n==null||typeof n==\"boolean\"||n===\"\"?\"\":t||typeof n!=\"number\"||n===0||Ct.hasOwnProperty(e)&&Ct[e]?(\"\"+n).trim():n+\"px\"}function Us(e,n){e=e.style;for(var t in n)if(n.hasOwnProperty(t)){var r=t.indexOf(\"--\")===0,l=js(t,n[t],r);t===\"float\"&&(t=\"cssFloat\"),r?e.setProperty(t,l):e[t]=l}}var gf=j({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ko(e,n){if(n){if(gf[e]&&(n.children!=null||n.dangerouslySetInnerHTML!=null))throw Error(h(137,e));if(n.dangerouslySetInnerHTML!=null){if(n.children!=null)throw Error(h(60));if(typeof n.dangerouslySetInnerHTML!=\"object\"||!(\"__html\"in n.dangerouslySetInnerHTML))throw Error(h(61))}if(n.style!=null&&typeof n.style!=\"object\")throw Error(h(62))}}function Eo(e,n){if(e.indexOf(\"-\")===-1)return typeof n.is==\"string\";switch(e){case\"annotation-xml\":case\"color-profile\":case\"font-face\":case\"font-face-src\":case\"font-face-uri\":case\"font-face-format\":case\"font-face-name\":case\"missing-glyph\":return!1;default:return!0}}var _o=null;function au(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Co=null,Xn=null,Gn=null;function Pi(e){if(e=qt(e)){if(typeof Co!=\"function\")throw Error(h(280));var n=e.stateNode;n&&(n=pl(n),Co(e.stateNode,e.type,n))}}function Vs(e){Xn?Gn?Gn.push(e):Gn=[e]:Xn=e}function As(){if(Xn){var e=Xn,n=Gn;if(Gn=Xn=null,Pi(e),n)for(e=0;e<n.length;e++)Pi(n[e])}}function Hs(e,n){return e(n)}function Bs(){}var Ql=!1;function Ws(e,n,t){if(Ql)return e(n,t);Ql=!0;try{return Hs(e,n,t)}finally{Ql=!1,(Xn!==null||Gn!==null)&&(Bs(),As())}}function It(e,n){var t=e.stateNode;if(t===null)return null;var r=pl(t);if(r===null)return null;t=r[n];e:switch(n){case\"onClick\":case\"onClickCapture\":case\"onDoubleClick\":case\"onDoubleClickCapture\":case\"onMouseDown\":case\"onMouseDownCapture\":case\"onMouseMove\":case\"onMouseMoveCapture\":case\"onMouseUp\":case\"onMouseUpCapture\":case\"onMouseEnter\":(r=!r.disabled)||(e=e.type,r=!(e===\"button\"||e===\"input\"||e===\"select\"||e===\"textarea\")),e=!r;break e;default:e=!1}if(e)return null;if(t&&typeof t!=\"function\")throw Error(h(231,n,typeof t));return t}var xo=!1;if(We)try{Dn={},Object.defineProperty(Dn,\"passive\",{get:function(){xo=!0}}),window.addEventListener(\"test\",Dn,Dn),window.removeEventListener(\"test\",Dn,Dn)}catch{xo=!1}var Dn;function wf(e,n,t,r,l,o,u,i,s){var f=Array.prototype.slice.call(arguments,3);try{n.apply(t,f)}catch(m){this.onError(m)}}var xt=!1,Ar=null,Hr=!1,No=null,Sf={onError:function(e){xt=!0,Ar=e}};function kf(e,n,t,r,l,o,u,i,s){xt=!1,Ar=null,wf.apply(Sf,arguments)}function Ef(e,n,t,r,l,o,u,i,s){if(kf.apply(this,arguments),xt){if(xt){var f=Ar;xt=!1,Ar=null}else throw Error(h(198));Hr||(Hr=!0,No=f)}}function Rn(e){var n=e,t=e;if(e.alternate)for(;n.return;)n=n.return;else{e=n;do n=e,n.flags&4098&&(t=n.return),e=n.return;while(e)}return n.tag===3?t:null}function $s(e){if(e.tag===13){var n=e.memoizedState;if(n===null&&(e=e.alternate,e!==null&&(n=e.memoizedState)),n!==null)return n.dehydrated}return null}function zi(e){if(Rn(e)!==e)throw Error(h(188))}function _f(e){var n=e.alternate;if(!n){if(n=Rn(e),n===null)throw Error(h(188));return n!==e?null:e}for(var t=e,r=n;;){var l=t.return;if(l===null)break;var o=l.alternate;if(o===null){if(r=l.return,r!==null){t=r;continue}break}if(l.child===o.child){for(o=l.child;o;){if(o===t)return zi(l),e;if(o===r)return zi(l),n;o=o.sibling}throw Error(h(188))}if(t.return!==r.return)t=l,r=o;else{for(var u=!1,i=l.child;i;){if(i===t){u=!0,t=l,r=o;break}if(i===r){u=!0,r=l,t=o;break}i=i.sibling}if(!u){for(i=o.child;i;){if(i===t){u=!0,t=o,r=l;break}if(i===r){u=!0,r=o,t=l;break}i=i.sibling}if(!u)throw Error(h(189))}}if(t.alternate!==r)throw Error(h(190))}if(t.tag!==3)throw Error(h(188));return t.stateNode.current===t?e:n}function Qs(e){return e=_f(e),e!==null?Ks(e):null}function Ks(e){if(e.tag===5||e.tag===6)return e;for(e=e.child;e!==null;){var n=Ks(e);if(n!==null)return n;e=e.sibling}return null}var Ys=pe.unstable_scheduleCallback,Ti=pe.unstable_cancelCallback,Cf=pe.unstable_shouldYield,xf=pe.unstable_requestPaint,A=pe.unstable_now,Nf=pe.unstable_getCurrentPriorityLevel,cu=pe.unstable_ImmediatePriority,Xs=pe.unstable_UserBlockingPriority,Br=pe.unstable_NormalPriority,Pf=pe.unstable_LowPriority,Gs=pe.unstable_IdlePriority,al=null,Ie=null;function zf(e){if(Ie&&typeof Ie.onCommitFiberRoot==\"function\")try{Ie.onCommitFiberRoot(al,e,void 0,(e.current.flags&128)===128)}catch{}}var ze=Math.clz32?Math.clz32:Rf,Tf=Math.log,Lf=Math.LN2;function Rf(e){return e>>>=0,e===0?32:31-(Tf(e)/Lf|0)|0}var pr=64,mr=4194304;function Et(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Wr(e,n){var t=e.pendingLanes;if(t===0)return 0;var r=0,l=e.suspendedLanes,o=e.pingedLanes,u=t&268435455;if(u!==0){var i=u&~l;i!==0?r=Et(i):(o&=u,o!==0&&(r=Et(o)))}else u=t&~l,u!==0?r=Et(u):o!==0&&(r=Et(o));if(r===0)return 0;if(n!==0&&n!==r&&!(n&l)&&(l=r&-r,o=n&-n,l>=o||l===16&&(o&4194240)!==0))return n;if(r&4&&(r|=t&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=r;0<n;)t=31-ze(n),l=1<<t,r|=e[t],n&=~l;return r}function Of(e,n){switch(e){case 1:case 2:case 4:return n+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return n+5e3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Df(e,n){for(var t=e.suspendedLanes,r=e.pingedLanes,l=e.expirationTimes,o=e.pendingLanes;0<o;){var u=31-ze(o),i=1<<u,s=l[u];s===-1?(!(i&t)||i&r)&&(l[u]=Of(i,n)):s<=n&&(e.expiredLanes|=i),o&=~i}}function Po(e){return e=e.pendingLanes&-1073741825,e!==0?e:e&1073741824?1073741824:0}function Zs(){var e=pr;return pr<<=1,!(pr&4194240)&&(pr=64),e}function Kl(e){for(var n=[],t=0;31>t;t++)n.push(e);return n}function Zt(e,n,t){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-ze(n),e[n]=t}function Mf(e,n){var t=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<t;){var l=31-ze(t),o=1<<l;n[l]=0,r[l]=-1,e[l]=-1,t&=~o}}function fu(e,n){var t=e.entangledLanes|=n;for(e=e.entanglements;t;){var r=31-ze(t),l=1<<r;l&n|e[r]&n&&(e[r]|=n),t&=~l}}var T=0;function Js(e){return e&=-e,1<e?4<e?e&268435455?16:536870912:4:1}var qs,du,bs,ea,na,zo=!1,vr=[],rn=null,ln=null,on=null,Ft=new Map,jt=new Map,be=[],If=\"mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit\".split(\" \");function Li(e,n){switch(e){case\"focusin\":case\"focusout\":rn=null;break;case\"dragenter\":case\"dragleave\":ln=null;break;case\"mouseover\":case\"mouseout\":on=null;break;case\"pointerover\":case\"pointerout\":Ft.delete(n.pointerId);break;case\"gotpointercapture\":case\"lostpointercapture\":jt.delete(n.pointerId)}}function pt(e,n,t,r,l,o){return e===null||e.nativeEvent!==o?(e={blockedOn:n,domEventName:t,eventSystemFlags:r,nativeEvent:o,targetContainers:[l]},n!==null&&(n=qt(n),n!==null&&du(n)),e):(e.eventSystemFlags|=r,n=e.targetContainers,l!==null&&n.indexOf(l)===-1&&n.push(l),e)}function Ff(e,n,t,r,l){switch(n){case\"focusin\":return rn=pt(rn,e,n,t,r,l),!0;case\"dragenter\":return ln=pt(ln,e,n,t,r,l),!0;case\"mouseover\":return on=pt(on,e,n,t,r,l),!0;case\"pointerover\":var o=l.pointerId;return Ft.set(o,pt(Ft.get(o)||null,e,n,t,r,l)),!0;case\"gotpointercapture\":return o=l.pointerId,jt.set(o,pt(jt.get(o)||null,e,n,t,r,l)),!0}return!1}function ta(e){var n=Sn(e.target);if(n!==null){var t=Rn(n);if(t!==null){if(n=t.tag,n===13){if(n=$s(t),n!==null){e.blockedOn=n,na(e.priority,function(){bs(t)});return}}else if(n===3&&t.stateNode.current.memoizedState.isDehydrated){e.blockedOn=t.tag===3?t.stateNode.containerInfo:null;return}}}e.blockedOn=null}function Tr(e){if(e.blockedOn!==null)return!1;for(var n=e.targetContainers;0<n.length;){var t=To(e.domEventName,e.eventSystemFlags,n[0],e.nativeEvent);if(t===null){t=e.nativeEvent;var r=new t.constructor(t.type,t);_o=r,t.target.dispatchEvent(r),_o=null}else return n=qt(t),n!==null&&du(n),e.blockedOn=t,!1;n.shift()}return!0}function Ri(e,n,t){Tr(e)&&t.delete(n)}function jf(){zo=!1,rn!==null&&Tr(rn)&&(rn=null),ln!==null&&Tr(ln)&&(ln=null),on!==null&&Tr(on)&&(on=null),Ft.forEach(Ri),jt.forEach(Ri)}function mt(e,n){e.blockedOn===n&&(e.blockedOn=null,zo||(zo=!0,pe.unstable_scheduleCallback(pe.unstable_NormalPriority,jf)))}function Ut(e){function n(l){return mt(l,e)}if(0<vr.length){mt(vr[0],e);for(var t=1;t<vr.length;t++){var r=vr[t];r.blockedOn===e&&(r.blockedOn=null)}}for(rn!==null&&mt(rn,e),ln!==null&&mt(ln,e),on!==null&&mt(on,e),Ft.forEach(n),jt.forEach(n),t=0;t<be.length;t++)r=be[t],r.blockedOn===e&&(r.blockedOn=null);for(;0<be.length&&(t=be[0],t.blockedOn===null);)ta(t),t.blockedOn===null&&be.shift()}var Zn=Ye.ReactCurrentBatchConfig,$r=!0;function Uf(e,n,t,r){var l=T,o=Zn.transition;Zn.transition=null;try{T=1,pu(e,n,t,r)}finally{T=l,Zn.transition=o}}function Vf(e,n,t,r){var l=T,o=Zn.transition;Zn.transition=null;try{T=4,pu(e,n,t,r)}finally{T=l,Zn.transition=o}}function pu(e,n,t,r){if($r){var l=To(e,n,t,r);if(l===null)bl(e,n,r,Qr,t),Li(e,r);else if(Ff(l,e,n,t,r))r.stopPropagation();else if(Li(e,r),n&4&&-1<If.indexOf(e)){for(;l!==null;){var o=qt(l);if(o!==null&&qs(o),o=To(e,n,t,r),o===null&&bl(e,n,r,Qr,t),o===l)break;l=o}l!==null&&r.stopPropagation()}else bl(e,n,r,null,t)}}var Qr=null;function To(e,n,t,r){if(Qr=null,e=au(r),e=Sn(e),e!==null)if(n=Rn(e),n===null)e=null;else if(t=n.tag,t===13){if(e=$s(n),e!==null)return e;e=null}else if(t===3){if(n.stateNode.current.memoizedState.isDehydrated)return n.tag===3?n.stateNode.containerInfo:null;e=null}else n!==e&&(e=null);return Qr=e,null}function ra(e){switch(e){case\"cancel\":case\"click\":case\"close\":case\"contextmenu\":case\"copy\":case\"cut\":case\"auxclick\":case\"dblclick\":case\"dragend\":case\"dragstart\":case\"drop\":case\"focusin\":case\"focusout\":case\"input\":case\"invalid\":case\"keydown\":case\"keypress\":case\"keyup\":case\"mousedown\":case\"mouseup\":case\"paste\":case\"pause\":case\"play\":case\"pointercancel\":case\"pointerdown\":case\"pointerup\":case\"ratechange\":case\"reset\":case\"resize\":case\"seeked\":case\"submit\":case\"touchcancel\":case\"touchend\":case\"touchstart\":case\"volumechange\":case\"change\":case\"selectionchange\":case\"textInput\":case\"compositionstart\":case\"compositionend\":case\"compositionupdate\":case\"beforeblur\":case\"afterblur\":case\"beforeinput\":case\"blur\":case\"fullscreenchange\":case\"focus\":case\"hashchange\":case\"popstate\":case\"select\":case\"selectstart\":return 1;case\"drag\":case\"dragenter\":case\"dragexit\":case\"dragleave\":case\"dragover\":case\"mousemove\":case\"mouseout\":case\"mouseover\":case\"pointermove\":case\"pointerout\":case\"pointerover\":case\"scroll\":case\"toggle\":case\"touchmove\":case\"wheel\":case\"mouseenter\":case\"mouseleave\":case\"pointerenter\":case\"pointerleave\":return 4;case\"message\":switch(Nf()){case cu:return 1;case Xs:return 4;case Br:case Pf:return 16;case Gs:return 536870912;default:return 16}default:return 16}}var nn=null,mu=null,Lr=null;function la(){if(Lr)return Lr;var e,n=mu,t=n.length,r,l=\"value\"in nn?nn.value:nn.textContent,o=l.length;for(e=0;e<t&&n[e]===l[e];e++);var u=t-e;for(r=1;r<=u&&n[t-r]===l[o-r];r++);return Lr=l.slice(e,1<r?1-r:void 0)}function Rr(e){var n=e.keyCode;return\"charCode\"in e?(e=e.charCode,e===0&&n===13&&(e=13)):e=n,e===10&&(e=13),32<=e||e===13?e:0}function hr(){return!0}function Oi(){return!1}function me(e){function n(t,r,l,o,u){this._reactName=t,this._targetInst=l,this.type=r,this.nativeEvent=o,this.target=u,this.currentTarget=null;for(var i in e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(o):o[i]);return this.isDefaultPrevented=(o.defaultPrevented!=null?o.defaultPrevented:o.returnValue===!1)?hr:Oi,this.isPropagationStopped=Oi,this}return j(n.prototype,{preventDefault:function(){this.defaultPrevented=!0;var t=this.nativeEvent;t&&(t.preventDefault?t.preventDefault():typeof t.returnValue!=\"unknown\"&&(t.returnValue=!1),this.isDefaultPrevented=hr)},stopPropagation:function(){var t=this.nativeEvent;t&&(t.stopPropagation?t.stopPropagation():typeof t.cancelBubble!=\"unknown\"&&(t.cancelBubble=!0),this.isPropagationStopped=hr)},persist:function(){},isPersistent:hr}),n}var ut={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},vu=me(ut),Jt=j({},ut,{view:0,detail:0}),Af=me(Jt),Yl,Xl,vt,cl=j({},Jt,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:hu,button:0,buttons:0,relatedTarget:function(e){return e.relatedTarget===void 0?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return\"movementX\"in e?e.movementX:(e!==vt&&(vt&&e.type===\"mousemove\"?(Yl=e.screenX-vt.screenX,Xl=e.screenY-vt.screenY):Xl=Yl=0,vt=e),Yl)},movementY:function(e){return\"movementY\"in e?e.movementY:Xl}}),Di=me(cl),Hf=j({},cl,{dataTransfer:0}),Bf=me(Hf),Wf=j({},Jt,{relatedTarget:0}),Gl=me(Wf),$f=j({},ut,{animationName:0,elapsedTime:0,pseudoElement:0}),Qf=me($f),Kf=j({},ut,{clipboardData:function(e){return\"clipboardData\"in e?e.clipboardData:window.clipboardData}}),Yf=me(Kf),Xf=j({},ut,{data:0}),Mi=me(Xf),Gf={Esc:\"Escape\",Spacebar:\" \",Left:\"ArrowLeft\",Up:\"ArrowUp\",Right:\"ArrowRight\",Down:\"ArrowDown\",Del:\"Delete\",Win:\"OS\",Menu:\"ContextMenu\",Apps:\"ContextMenu\",Scroll:\"ScrollLock\",MozPrintableKey:\"Unidentified\"},Zf={8:\"Backspace\",9:\"Tab\",12:\"Clear\",13:\"Enter\",16:\"Shift\",17:\"Control\",18:\"Alt\",19:\"Pause\",20:\"CapsLock\",27:\"Escape\",32:\" \",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"ArrowLeft\",38:\"ArrowUp\",39:\"ArrowRight\",40:\"ArrowDown\",45:\"Insert\",46:\"Delete\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"NumLock\",145:\"ScrollLock\",224:\"Meta\"},Jf={Alt:\"altKey\",Control:\"ctrlKey\",Meta:\"metaKey\",Shift:\"shiftKey\"};function qf(e){var n=this.nativeEvent;return n.getModifierState?n.getModifierState(e):(e=Jf[e])?!!n[e]:!1}function hu(){return qf}var bf=j({},Jt,{key:function(e){if(e.key){var n=Gf[e.key]||e.key;if(n!==\"Unidentified\")return n}return e.type===\"keypress\"?(e=Rr(e),e===13?\"Enter\":String.fromCharCode(e)):e.type===\"keydown\"||e.type===\"keyup\"?Zf[e.keyCode]||\"Unidentified\":\"\"},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:hu,charCode:function(e){return e.type===\"keypress\"?Rr(e):0},keyCode:function(e){return e.type===\"keydown\"||e.type===\"keyup\"?e.keyCode:0},which:function(e){return e.type===\"keypress\"?Rr(e):e.type===\"keydown\"||e.type===\"keyup\"?e.keyCode:0}}),ed=me(bf),nd=j({},cl,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),Ii=me(nd),td=j({},Jt,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:hu}),rd=me(td),ld=j({},ut,{propertyName:0,elapsedTime:0,pseudoElement:0}),od=me(ld),ud=j({},cl,{deltaX:function(e){return\"deltaX\"in e?e.deltaX:\"wheelDeltaX\"in e?-e.wheelDeltaX:0},deltaY:function(e){return\"deltaY\"in e?e.deltaY:\"wheelDeltaY\"in e?-e.wheelDeltaY:\"wheelDelta\"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),id=me(ud),sd=[9,13,27,32],yu=We&&\"CompositionEvent\"in window,Nt=null;We&&\"documentMode\"in document&&(Nt=document.documentMode);var ad=We&&\"TextEvent\"in window&&!Nt,oa=We&&(!yu||Nt&&8<Nt&&11>=Nt),Fi=\" \",ji=!1;function ua(e,n){switch(e){case\"keyup\":return sd.indexOf(n.keyCode)!==-1;case\"keydown\":return n.keyCode!==229;case\"keypress\":case\"mousedown\":case\"focusout\":return!0;default:return!1}}function ia(e){return e=e.detail,typeof e==\"object\"&&\"data\"in e?e.data:null}var jn=!1;function cd(e,n){switch(e){case\"compositionend\":return ia(n);case\"keypress\":return n.which!==32?null:(ji=!0,Fi);case\"textInput\":return e=n.data,e===Fi&&ji?null:e;default:return null}}function fd(e,n){if(jn)return e===\"compositionend\"||!yu&&ua(e,n)?(e=la(),Lr=mu=nn=null,jn=!1,e):null;switch(e){case\"paste\":return null;case\"keypress\":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1<n.char.length)return n.char;if(n.which)return String.fromCharCode(n.which)}return null;case\"compositionend\":return oa&&n.locale!==\"ko\"?null:n.data;default:return null}}var dd={color:!0,date:!0,datetime:!0,\"datetime-local\":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Ui(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n===\"input\"?!!dd[e.type]:n===\"textarea\"}function sa(e,n,t,r){Vs(r),n=Kr(n,\"onChange\"),0<n.length&&(t=new vu(\"onChange\",\"change\",null,t,r),e.push({event:t,listeners:n}))}var Pt=null,Vt=null;function pd(e){wa(e,0)}function fl(e){var n=An(e);if(Os(n))return e}function md(e,n){if(e===\"change\")return n}var aa=!1;We&&(We?(gr=\"oninput\"in document,gr||(Zl=document.createElement(\"div\"),Zl.setAttribute(\"oninput\",\"return;\"),gr=typeof Zl.oninput==\"function\"),yr=gr):yr=!1,aa=yr&&(!document.documentMode||9<document.documentMode));var yr,gr,Zl;function Vi(){Pt&&(Pt.detachEvent(\"onpropertychange\",ca),Vt=Pt=null)}function ca(e){if(e.propertyName===\"value\"&&fl(Vt)){var n=[];sa(n,Vt,e,au(e)),Ws(pd,n)}}function vd(e,n,t){e===\"focusin\"?(Vi(),Pt=n,Vt=t,Pt.attachEvent(\"onpropertychange\",ca)):e===\"focusout\"&&Vi()}function hd(e){if(e===\"selectionchange\"||e===\"keyup\"||e===\"keydown\")return fl(Vt)}function yd(e,n){if(e===\"click\")return fl(n)}function gd(e,n){if(e===\"input\"||e===\"change\")return fl(n)}function wd(e,n){return e===n&&(e!==0||1/e===1/n)||e!==e&&n!==n}var Le=typeof Object.is==\"function\"?Object.is:wd;function At(e,n){if(Le(e,n))return!0;if(typeof e!=\"object\"||e===null||typeof n!=\"object\"||n===null)return!1;var t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(r=0;r<t.length;r++){var l=t[r];if(!co.call(n,l)||!Le(e[l],n[l]))return!1}return!0}function Ai(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function Hi(e,n){var t=Ai(e);e=0;for(var r;t;){if(t.nodeType===3){if(r=e+t.textContent.length,e<=n&&r>=n)return{node:t,offset:n-e};e=r}e:{for(;t;){if(t.nextSibling){t=t.nextSibling;break e}t=t.parentNode}t=void 0}t=Ai(t)}}function fa(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?fa(e,n.parentNode):\"contains\"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function da(){for(var e=window,n=Vr();n instanceof e.HTMLIFrameElement;){try{var t=typeof n.contentWindow.location.href==\"string\"}catch{t=!1}if(t)e=n.contentWindow;else break;n=Vr(e.document)}return n}function gu(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n===\"input\"&&(e.type===\"text\"||e.type===\"search\"||e.type===\"tel\"||e.type===\"url\"||e.type===\"password\")||n===\"textarea\"||e.contentEditable===\"true\")}function Sd(e){var n=da(),t=e.focusedElem,r=e.selectionRange;if(n!==t&&t&&t.ownerDocument&&fa(t.ownerDocument.documentElement,t)){if(r!==null&&gu(t)){if(n=r.start,e=r.end,e===void 0&&(e=n),\"selectionStart\"in t)t.selectionStart=n,t.selectionEnd=Math.min(e,t.value.length);else if(e=(n=t.ownerDocument||document)&&n.defaultView||window,e.getSelection){e=e.getSelection();var l=t.textContent.length,o=Math.min(r.start,l);r=r.end===void 0?o:Math.min(r.end,l),!e.extend&&o>r&&(l=r,r=o,o=l),l=Hi(t,o);var u=Hi(t,r);l&&u&&(e.rangeCount!==1||e.anchorNode!==l.node||e.anchorOffset!==l.offset||e.focusNode!==u.node||e.focusOffset!==u.offset)&&(n=n.createRange(),n.setStart(l.node,l.offset),e.removeAllRanges(),o>r?(e.addRange(n),e.extend(u.node,u.offset)):(n.setEnd(u.node,u.offset),e.addRange(n)))}}for(n=[],e=t;e=e.parentNode;)e.nodeType===1&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof t.focus==\"function\"&&t.focus(),t=0;t<n.length;t++)e=n[t],e.element.scrollLeft=e.left,e.element.scrollTop=e.top}}var kd=We&&\"documentMode\"in document&&11>=document.documentMode,Un=null,Lo=null,zt=null,Ro=!1;function Bi(e,n,t){var r=t.window===t?t.document:t.nodeType===9?t:t.ownerDocument;Ro||Un==null||Un!==Vr(r)||(r=Un,\"selectionStart\"in r&&gu(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),zt&&At(zt,r)||(zt=r,r=Kr(Lo,\"onSelect\"),0<r.length&&(n=new vu(\"onSelect\",\"select\",null,n,t),e.push({event:n,listeners:r}),n.target=Un)))}function wr(e,n){var t={};return t[e.toLowerCase()]=n.toLowerCase(),t[\"Webkit\"+e]=\"webkit\"+n,t[\"Moz\"+e]=\"moz\"+n,t}var Vn={animationend:wr(\"Animation\",\"AnimationEnd\"),animationiteration:wr(\"Animation\",\"AnimationIteration\"),animationstart:wr(\"Animation\",\"AnimationStart\"),transitionend:wr(\"Transition\",\"TransitionEnd\")},Jl={},pa={};We&&(pa=document.createElement(\"div\").style,\"AnimationEvent\"in window||(delete Vn.animationend.animation,delete Vn.animationiteration.animation,delete Vn.animationstart.animation),\"TransitionEvent\"in window||delete Vn.transitionend.transition);function dl(e){if(Jl[e])return Jl[e];if(!Vn[e])return e;var n=Vn[e],t;for(t in n)if(n.hasOwnProperty(t)&&t in pa)return Jl[e]=n[t];return e}var ma=dl(\"animationend\"),va=dl(\"animationiteration\"),ha=dl(\"animationstart\"),ya=dl(\"transitionend\"),ga=new Map,Wi=\"abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel\".split(\" \");function mn(e,n){ga.set(e,n),Ln(n,[e])}for(Sr=0;Sr<Wi.length;Sr++)kr=Wi[Sr],$i=kr.toLowerCase(),Qi=kr[0].toUpperCase()+kr.slice(1),mn($i,\"on\"+Qi);var kr,$i,Qi,Sr;mn(ma,\"onAnimationEnd\");mn(va,\"onAnimationIteration\");mn(ha,\"onAnimationStart\");mn(\"dblclick\",\"onDoubleClick\");mn(\"focusin\",\"onFocus\");mn(\"focusout\",\"onBlur\");mn(ya,\"onTransitionEnd\");bn(\"onMouseEnter\",[\"mouseout\",\"mouseover\"]);bn(\"onMouseLeave\",[\"mouseout\",\"mouseover\"]);bn(\"onPointerEnter\",[\"pointerout\",\"pointerover\"]);bn(\"onPointerLeave\",[\"pointerout\",\"pointerover\"]);Ln(\"onChange\",\"change click focusin focusout input keydown keyup selectionchange\".split(\" \"));Ln(\"onSelect\",\"focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange\".split(\" \"));Ln(\"onBeforeInput\",[\"compositionend\",\"keypress\",\"textInput\",\"paste\"]);Ln(\"onCompositionEnd\",\"compositionend focusout keydown keypress keyup mousedown\".split(\" \"));Ln(\"onCompositionStart\",\"compositionstart focusout keydown keypress keyup mousedown\".split(\" \"));Ln(\"onCompositionUpdate\",\"compositionupdate focusout keydown keypress keyup mousedown\".split(\" \"));var _t=\"abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting\".split(\" \"),Ed=new Set(\"cancel close invalid load scroll toggle\".split(\" \").concat(_t));function Ki(e,n,t){var r=e.type||\"unknown-event\";e.currentTarget=t,Ef(r,n,void 0,e),e.currentTarget=null}function wa(e,n){n=(n&4)!==0;for(var t=0;t<e.length;t++){var r=e[t],l=r.event;r=r.listeners;e:{var o=void 0;if(n)for(var u=r.length-1;0<=u;u--){var i=r[u],s=i.instance,f=i.currentTarget;if(i=i.listener,s!==o&&l.isPropagationStopped())break e;Ki(l,i,f),o=s}else for(u=0;u<r.length;u++){if(i=r[u],s=i.instance,f=i.currentTarget,i=i.listener,s!==o&&l.isPropagationStopped())break e;Ki(l,i,f),o=s}}}if(Hr)throw e=No,Hr=!1,No=null,e}function O(e,n){var t=n[Fo];t===void 0&&(t=n[Fo]=new Set);var r=e+\"__bubble\";t.has(r)||(Sa(n,e,2,!1),t.add(r))}function ql(e,n,t){var r=0;n&&(r|=4),Sa(t,e,r,n)}var Er=\"_reactListening\"+Math.random().toString(36).slice(2);function Ht(e){if(!e[Er]){e[Er]=!0,Ps.forEach(function(t){t!==\"selectionchange\"&&(Ed.has(t)||ql(t,!1,e),ql(t,!0,e))});var n=e.nodeType===9?e:e.ownerDocument;n===null||n[Er]||(n[Er]=!0,ql(\"selectionchange\",!1,n))}}function Sa(e,n,t,r){switch(ra(n)){case 1:var l=Uf;break;case 4:l=Vf;break;default:l=pu}t=l.bind(null,n,t,e),l=void 0,!xo||n!==\"touchstart\"&&n!==\"touchmove\"&&n!==\"wheel\"||(l=!0),r?l!==void 0?e.addEventListener(n,t,{capture:!0,passive:l}):e.addEventListener(n,t,!0):l!==void 0?e.addEventListener(n,t,{passive:l}):e.addEventListener(n,t,!1)}function bl(e,n,t,r,l){var o=r;if(!(n&1)&&!(n&2)&&r!==null)e:for(;;){if(r===null)return;var u=r.tag;if(u===3||u===4){var i=r.stateNode.containerInfo;if(i===l||i.nodeType===8&&i.parentNode===l)break;if(u===4)for(u=r.return;u!==null;){var s=u.tag;if((s===3||s===4)&&(s=u.stateNode.containerInfo,s===l||s.nodeType===8&&s.parentNode===l))return;u=u.return}for(;i!==null;){if(u=Sn(i),u===null)return;if(s=u.tag,s===5||s===6){r=o=u;continue e}i=i.parentNode}}r=r.return}Ws(function(){var f=o,m=au(t),v=[];e:{var p=ga.get(e);if(p!==void 0){var g=vu,S=e;switch(e){case\"keypress\":if(Rr(t)===0)break e;case\"keydown\":case\"keyup\":g=ed;break;case\"focusin\":S=\"focus\",g=Gl;break;case\"focusout\":S=\"blur\",g=Gl;break;case\"beforeblur\":case\"afterblur\":g=Gl;break;case\"click\":if(t.button===2)break e;case\"auxclick\":case\"dblclick\":case\"mousedown\":case\"mousemove\":case\"mouseup\":case\"mouseout\":case\"mouseover\":case\"contextmenu\":g=Di;break;case\"drag\":case\"dragend\":case\"dragenter\":case\"dragexit\":case\"dragleave\":case\"dragover\":case\"dragstart\":case\"drop\":g=Bf;break;case\"touchcancel\":case\"touchend\":case\"touchmove\":case\"touchstart\":g=rd;break;case ma:case va:case ha:g=Qf;break;case ya:g=od;break;case\"scroll\":g=Af;break;case\"wheel\":g=id;break;case\"copy\":case\"cut\":case\"paste\":g=Yf;break;case\"gotpointercapture\":case\"lostpointercapture\":case\"pointercancel\":case\"pointerdown\":case\"pointermove\":case\"pointerout\":case\"pointerover\":case\"pointerup\":g=Ii}var k=(n&4)!==0,V=!k&&e===\"scroll\",c=k?p!==null?p+\"Capture\":null:p;k=[];for(var a=f,d;a!==null;){d=a;var y=d.stateNode;if(d.tag===5&&y!==null&&(d=y,c!==null&&(y=It(a,c),y!=null&&k.push(Bt(a,y,d)))),V)break;a=a.return}0<k.length&&(p=new g(p,S,null,t,m),v.push({event:p,listeners:k}))}}if(!(n&7)){e:{if(p=e===\"mouseover\"||e===\"pointerover\",g=e===\"mouseout\"||e===\"pointerout\",p&&t!==_o&&(S=t.relatedTarget||t.fromElement)&&(Sn(S)||S[$e]))break e;if((g||p)&&(p=m.window===m?m:(p=m.ownerDocument)?p.defaultView||p.parentWindow:window,g?(S=t.relatedTarget||t.toElement,g=f,S=S?Sn(S):null,S!==null&&(V=Rn(S),S!==V||S.tag!==5&&S.tag!==6)&&(S=null)):(g=null,S=f),g!==S)){if(k=Di,y=\"onMouseLeave\",c=\"onMouseEnter\",a=\"mouse\",(e===\"pointerout\"||e===\"pointerover\")&&(k=Ii,y=\"onPointerLeave\",c=\"onPointerEnter\",a=\"pointer\"),V=g==null?p:An(g),d=S==null?p:An(S),p=new k(y,a+\"leave\",g,t,m),p.target=V,p.relatedTarget=d,y=null,Sn(m)===f&&(k=new k(c,a+\"enter\",S,t,m),k.target=d,k.relatedTarget=V,y=k),V=y,g&&S)n:{for(k=g,c=S,a=0,d=k;d;d=Mn(d))a++;for(d=0,y=c;y;y=Mn(y))d++;for(;0<a-d;)k=Mn(k),a--;for(;0<d-a;)c=Mn(c),d--;for(;a--;){if(k===c||c!==null&&k===c.alternate)break n;k=Mn(k),c=Mn(c)}k=null}else k=null;g!==null&&Yi(v,p,g,k,!1),S!==null&&V!==null&&Yi(v,V,S,k,!0)}}e:{if(p=f?An(f):window,g=p.nodeName&&p.nodeName.toLowerCase(),g===\"select\"||g===\"input\"&&p.type===\"file\")var E=md;else if(Ui(p))if(aa)E=gd;else{E=hd;var _=vd}else(g=p.nodeName)&&g.toLowerCase()===\"input\"&&(p.type===\"checkbox\"||p.type===\"radio\")&&(E=yd);if(E&&(E=E(e,f))){sa(v,E,t,m);break e}_&&_(e,p,f),e===\"focusout\"&&(_=p._wrapperState)&&_.controlled&&p.type===\"number\"&&go(p,\"number\",p.value)}switch(_=f?An(f):window,e){case\"focusin\":(Ui(_)||_.contentEditable===\"true\")&&(Un=_,Lo=f,zt=null);break;case\"focusout\":zt=Lo=Un=null;break;case\"mousedown\":Ro=!0;break;case\"contextmenu\":case\"mouseup\":case\"dragend\":Ro=!1,Bi(v,t,m);break;case\"selectionchange\":if(kd)break;case\"keydown\":case\"keyup\":Bi(v,t,m)}var C;if(yu)e:{switch(e){case\"compositionstart\":var x=\"onCompositionStart\";break e;case\"compositionend\":x=\"onCompositionEnd\";break e;case\"compositionupdate\":x=\"onCompositionUpdate\";break e}x=void 0}else jn?ua(e,t)&&(x=\"onCompositionEnd\"):e===\"keydown\"&&t.keyCode===229&&(x=\"onCompositionStart\");x&&(oa&&t.locale!==\"ko\"&&(jn||x!==\"onCompositionStart\"?x===\"onCompositionEnd\"&&jn&&(C=la()):(nn=m,mu=\"value\"in nn?nn.value:nn.textContent,jn=!0)),_=Kr(f,x),0<_.length&&(x=new Mi(x,e,null,t,m),v.push({event:x,listeners:_}),C?x.data=C:(C=ia(t),C!==null&&(x.data=C)))),(C=ad?cd(e,t):fd(e,t))&&(f=Kr(f,\"onBeforeInput\"),0<f.length&&(m=new Mi(\"onBeforeInput\",\"beforeinput\",null,t,m),v.push({event:m,listeners:f}),m.data=C))}wa(v,n)})}function Bt(e,n,t){return{instance:e,listener:n,currentTarget:t}}function Kr(e,n){for(var t=n+\"Capture\",r=[];e!==null;){var l=e,o=l.stateNode;l.tag===5&&o!==null&&(l=o,o=It(e,t),o!=null&&r.unshift(Bt(e,o,l)),o=It(e,n),o!=null&&r.push(Bt(e,o,l))),e=e.return}return r}function Mn(e){if(e===null)return null;do e=e.return;while(e&&e.tag!==5);return e||null}function Yi(e,n,t,r,l){for(var o=n._reactName,u=[];t!==null&&t!==r;){var i=t,s=i.alternate,f=i.stateNode;if(s!==null&&s===r)break;i.tag===5&&f!==null&&(i=f,l?(s=It(t,o),s!=null&&u.unshift(Bt(t,s,i))):l||(s=It(t,o),s!=null&&u.push(Bt(t,s,i)))),t=t.return}u.length!==0&&e.push({event:n,listeners:u})}var _d=/\\r\\n?/g,Cd=/\\u0000|\\uFFFD/g;function Xi(e){return(typeof e==\"string\"?e:\"\"+e).replace(_d,`\n`).replace(Cd,\"\")}function _r(e,n,t){if(n=Xi(n),Xi(e)!==n&&t)throw Error(h(425))}function Yr(){}var Oo=null,Do=null;function Mo(e,n){return e===\"textarea\"||e===\"noscript\"||typeof n.children==\"string\"||typeof n.children==\"number\"||typeof n.dangerouslySetInnerHTML==\"object\"&&n.dangerouslySetInnerHTML!==null&&n.dangerouslySetInnerHTML.__html!=null}var Io=typeof setTimeout==\"function\"?setTimeout:void 0,xd=typeof clearTimeout==\"function\"?clearTimeout:void 0,Gi=typeof Promise==\"function\"?Promise:void 0,Nd=typeof queueMicrotask==\"function\"?queueMicrotask:typeof Gi<\"u\"?function(e){return Gi.resolve(null).then(e).catch(Pd)}:Io;function Pd(e){setTimeout(function(){throw e})}function eo(e,n){var t=n,r=0;do{var l=t.nextSibling;if(e.removeChild(t),l&&l.nodeType===8)if(t=l.data,t===\"/$\"){if(r===0){e.removeChild(l),Ut(n);return}r--}else t!==\"$\"&&t!==\"$?\"&&t!==\"$!\"||r++;t=l}while(t);Ut(n)}function un(e){for(;e!=null;e=e.nextSibling){var n=e.nodeType;if(n===1||n===3)break;if(n===8){if(n=e.data,n===\"$\"||n===\"$!\"||n===\"$?\")break;if(n===\"/$\")return null}}return e}function Zi(e){e=e.previousSibling;for(var n=0;e;){if(e.nodeType===8){var t=e.data;if(t===\"$\"||t===\"$!\"||t===\"$?\"){if(n===0)return e;n--}else t===\"/$\"&&n++}e=e.previousSibling}return null}var it=Math.random().toString(36).slice(2),Me=\"__reactFiber$\"+it,Wt=\"__reactProps$\"+it,$e=\"__reactContainer$\"+it,Fo=\"__reactEvents$\"+it,zd=\"__reactListeners$\"+it,Td=\"__reactHandles$\"+it;function Sn(e){var n=e[Me];if(n)return n;for(var t=e.parentNode;t;){if(n=t[$e]||t[Me]){if(t=n.alternate,n.child!==null||t!==null&&t.child!==null)for(e=Zi(e);e!==null;){if(t=e[Me])return t;e=Zi(e)}return n}e=t,t=e.parentNode}return null}function qt(e){return e=e[Me]||e[$e],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function An(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(h(33))}function pl(e){return e[Wt]||null}var jo=[],Hn=-1;function vn(e){return{current:e}}function D(e){0>Hn||(e.current=jo[Hn],jo[Hn]=null,Hn--)}function R(e,n){Hn++,jo[Hn]=e.current,e.current=n}var pn={},ee=vn(pn),ie=vn(!1),xn=pn;function et(e,n){var t=e.type.contextTypes;if(!t)return pn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===n)return r.__reactInternalMemoizedMaskedChildContext;var l={},o;for(o in t)l[o]=n[o];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=l),l}function se(e){return e=e.childContextTypes,e!=null}function Xr(){D(ie),D(ee)}function Ji(e,n,t){if(ee.current!==pn)throw Error(h(168));R(ee,n),R(ie,t)}function ka(e,n,t){var r=e.stateNode;if(n=n.childContextTypes,typeof r.getChildContext!=\"function\")return t;r=r.getChildContext();for(var l in r)if(!(l in n))throw Error(h(108,vf(e)||\"Unknown\",l));return j({},t,r)}function Gr(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||pn,xn=ee.current,R(ee,e),R(ie,ie.current),!0}function qi(e,n,t){var r=e.stateNode;if(!r)throw Error(h(169));t?(e=ka(e,n,xn),r.__reactInternalMemoizedMergedChildContext=e,D(ie),D(ee),R(ee,e)):D(ie),R(ie,t)}var Ve=null,ml=!1,no=!1;function Ea(e){Ve===null?Ve=[e]:Ve.push(e)}function Ld(e){ml=!0,Ea(e)}function hn(){if(!no&&Ve!==null){no=!0;var e=0,n=T;try{var t=Ve;for(T=1;e<t.length;e++){var r=t[e];do r=r(!0);while(r!==null)}Ve=null,ml=!1}catch(l){throw Ve!==null&&(Ve=Ve.slice(e+1)),Ys(cu,hn),l}finally{T=n,no=!1}}return null}var Bn=[],Wn=0,Zr=null,Jr=0,ye=[],ge=0,Nn=null,Ae=1,He=\"\";function gn(e,n){Bn[Wn++]=Jr,Bn[Wn++]=Zr,Zr=e,Jr=n}function _a(e,n,t){ye[ge++]=Ae,ye[ge++]=He,ye[ge++]=Nn,Nn=e;var r=Ae;e=He;var l=32-ze(r)-1;r&=~(1<<l),t+=1;var o=32-ze(n)+l;if(30<o){var u=l-l%5;o=(r&(1<<u)-1).toString(32),r>>=u,l-=u,Ae=1<<32-ze(n)+l|t<<l|r,He=o+e}else Ae=1<<o|t<<l|r,He=e}function wu(e){e.return!==null&&(gn(e,1),_a(e,1,0))}function Su(e){for(;e===Zr;)Zr=Bn[--Wn],Bn[Wn]=null,Jr=Bn[--Wn],Bn[Wn]=null;for(;e===Nn;)Nn=ye[--ge],ye[ge]=null,He=ye[--ge],ye[ge]=null,Ae=ye[--ge],ye[ge]=null}var de=null,fe=null,M=!1,Pe=null;function Ca(e,n){var t=we(5,null,null,0);t.elementType=\"DELETED\",t.stateNode=n,t.return=e,n=e.deletions,n===null?(e.deletions=[t],e.flags|=16):n.push(t)}function bi(e,n){switch(e.tag){case 5:var t=e.type;return n=n.nodeType!==1||t.toLowerCase()!==n.nodeName.toLowerCase()?null:n,n!==null?(e.stateNode=n,de=e,fe=un(n.firstChild),!0):!1;case 6:return n=e.pendingProps===\"\"||n.nodeType!==3?null:n,n!==null?(e.stateNode=n,de=e,fe=null,!0):!1;case 13:return n=n.nodeType!==8?null:n,n!==null?(t=Nn!==null?{id:Ae,overflow:He}:null,e.memoizedState={dehydrated:n,treeContext:t,retryLane:1073741824},t=we(18,null,null,0),t.stateNode=n,t.return=e,e.child=t,de=e,fe=null,!0):!1;default:return!1}}function Uo(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Vo(e){if(M){var n=fe;if(n){var t=n;if(!bi(e,n)){if(Uo(e))throw Error(h(418));n=un(t.nextSibling);var r=de;n&&bi(e,n)?Ca(r,t):(e.flags=e.flags&-4097|2,M=!1,de=e)}}else{if(Uo(e))throw Error(h(418));e.flags=e.flags&-4097|2,M=!1,de=e}}}function es(e){for(e=e.return;e!==null&&e.tag!==5&&e.tag!==3&&e.tag!==13;)e=e.return;de=e}function Cr(e){if(e!==de)return!1;if(!M)return es(e),M=!0,!1;var n;if((n=e.tag!==3)&&!(n=e.tag!==5)&&(n=e.type,n=n!==\"head\"&&n!==\"body\"&&!Mo(e.type,e.memoizedProps)),n&&(n=fe)){if(Uo(e))throw xa(),Error(h(418));for(;n;)Ca(e,n),n=un(n.nextSibling)}if(es(e),e.tag===13){if(e=e.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(h(317));e:{for(e=e.nextSibling,n=0;e;){if(e.nodeType===8){var t=e.data;if(t===\"/$\"){if(n===0){fe=un(e.nextSibling);break e}n--}else t!==\"$\"&&t!==\"$!\"&&t!==\"$?\"||n++}e=e.nextSibling}fe=null}}else fe=de?un(e.stateNode.nextSibling):null;return!0}function xa(){for(var e=fe;e;)e=un(e.nextSibling)}function nt(){fe=de=null,M=!1}function ku(e){Pe===null?Pe=[e]:Pe.push(e)}var Rd=Ye.ReactCurrentBatchConfig;function xe(e,n){if(e&&e.defaultProps){n=j({},n),e=e.defaultProps;for(var t in e)n[t]===void 0&&(n[t]=e[t]);return n}return n}var qr=vn(null),br=null,$n=null,Eu=null;function _u(){Eu=$n=br=null}function Cu(e){var n=qr.current;D(qr),e._currentValue=n}function Ao(e,n,t){for(;e!==null;){var r=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,r!==null&&(r.childLanes|=n)):r!==null&&(r.childLanes&n)!==n&&(r.childLanes|=n),e===t)break;e=e.return}}function Jn(e,n){br=e,Eu=$n=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&n&&(ue=!0),e.firstContext=null)}function ke(e){var n=e._currentValue;if(Eu!==e)if(e={context:e,memoizedValue:n,next:null},$n===null){if(br===null)throw Error(h(308));$n=e,br.dependencies={lanes:0,firstContext:e}}else $n=$n.next=e;return n}var kn=null;function xu(e){kn===null?kn=[e]:kn.push(e)}function Na(e,n,t,r){var l=n.interleaved;return l===null?(t.next=t,xu(n)):(t.next=l.next,l.next=t),n.interleaved=t,Qe(e,r)}function Qe(e,n){e.lanes|=n;var t=e.alternate;for(t!==null&&(t.lanes|=n),t=e,e=e.return;e!==null;)e.childLanes|=n,t=e.alternate,t!==null&&(t.childLanes|=n),t=e,e=e.return;return t.tag===3?t.stateNode:null}var qe=!1;function Nu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Pa(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Be(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function sn(e,n,t){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,P&2){var l=r.pending;return l===null?n.next=n:(n.next=l.next,l.next=n),r.pending=n,Qe(e,t)}return l=r.interleaved,l===null?(n.next=n,xu(r)):(n.next=l.next,l.next=n),r.interleaved=n,Qe(e,t)}function Or(e,n,t){if(n=n.updateQueue,n!==null&&(n=n.shared,(t&4194240)!==0)){var r=n.lanes;r&=e.pendingLanes,t|=r,n.lanes=t,fu(e,t)}}function ns(e,n){var t=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,t===r)){var l=null,o=null;if(t=t.firstBaseUpdate,t!==null){do{var u={eventTime:t.eventTime,lane:t.lane,tag:t.tag,payload:t.payload,callback:t.callback,next:null};o===null?l=o=u:o=o.next=u,t=t.next}while(t!==null);o===null?l=o=n:o=o.next=n}else l=o=n;t={baseState:r.baseState,firstBaseUpdate:l,lastBaseUpdate:o,shared:r.shared,effects:r.effects},e.updateQueue=t;return}e=t.lastBaseUpdate,e===null?t.firstBaseUpdate=n:e.next=n,t.lastBaseUpdate=n}function el(e,n,t,r){var l=e.updateQueue;qe=!1;var o=l.firstBaseUpdate,u=l.lastBaseUpdate,i=l.shared.pending;if(i!==null){l.shared.pending=null;var s=i,f=s.next;s.next=null,u===null?o=f:u.next=f,u=s;var m=e.alternate;m!==null&&(m=m.updateQueue,i=m.lastBaseUpdate,i!==u&&(i===null?m.firstBaseUpdate=f:i.next=f,m.lastBaseUpdate=s))}if(o!==null){var v=l.baseState;u=0,m=f=s=null,i=o;do{var p=i.lane,g=i.eventTime;if((r&p)===p){m!==null&&(m=m.next={eventTime:g,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var S=e,k=i;switch(p=n,g=t,k.tag){case 1:if(S=k.payload,typeof S==\"function\"){v=S.call(g,v,p);break e}v=S;break e;case 3:S.flags=S.flags&-65537|128;case 0:if(S=k.payload,p=typeof S==\"function\"?S.call(g,v,p):S,p==null)break e;v=j({},v,p);break e;case 2:qe=!0}}i.callback!==null&&i.lane!==0&&(e.flags|=64,p=l.effects,p===null?l.effects=[i]:p.push(i))}else g={eventTime:g,lane:p,tag:i.tag,payload:i.payload,callback:i.callback,next:null},m===null?(f=m=g,s=v):m=m.next=g,u|=p;if(i=i.next,i===null){if(i=l.shared.pending,i===null)break;p=i,i=p.next,p.next=null,l.lastBaseUpdate=p,l.shared.pending=null}}while(!0);if(m===null&&(s=v),l.baseState=s,l.firstBaseUpdate=f,l.lastBaseUpdate=m,n=l.shared.interleaved,n!==null){l=n;do u|=l.lane,l=l.next;while(l!==n)}else o===null&&(l.shared.lanes=0);zn|=u,e.lanes=u,e.memoizedState=v}}function ts(e,n,t){if(e=n.effects,n.effects=null,e!==null)for(n=0;n<e.length;n++){var r=e[n],l=r.callback;if(l!==null){if(r.callback=null,r=t,typeof l!=\"function\")throw Error(h(191,l));l.call(r)}}}var za=new Ns.Component().refs;function Ho(e,n,t,r){n=e.memoizedState,t=t(r,n),t=t==null?n:j({},n,t),e.memoizedState=t,e.lanes===0&&(e.updateQueue.baseState=t)}var vl={isMounted:function(e){return(e=e._reactInternals)?Rn(e)===e:!1},enqueueSetState:function(e,n,t){e=e._reactInternals;var r=re(),l=cn(e),o=Be(r,l);o.payload=n,t!=null&&(o.callback=t),n=sn(e,o,l),n!==null&&(Te(n,e,l,r),Or(n,e,l))},enqueueReplaceState:function(e,n,t){e=e._reactInternals;var r=re(),l=cn(e),o=Be(r,l);o.tag=1,o.payload=n,t!=null&&(o.callback=t),n=sn(e,o,l),n!==null&&(Te(n,e,l,r),Or(n,e,l))},enqueueForceUpdate:function(e,n){e=e._reactInternals;var t=re(),r=cn(e),l=Be(t,r);l.tag=2,n!=null&&(l.callback=n),n=sn(e,l,r),n!==null&&(Te(n,e,r,t),Or(n,e,r))}};function rs(e,n,t,r,l,o,u){return e=e.stateNode,typeof e.shouldComponentUpdate==\"function\"?e.shouldComponentUpdate(r,o,u):n.prototype&&n.prototype.isPureReactComponent?!At(t,r)||!At(l,o):!0}function Ta(e,n,t){var r=!1,l=pn,o=n.contextType;return typeof o==\"object\"&&o!==null?o=ke(o):(l=se(n)?xn:ee.current,r=n.contextTypes,o=(r=r!=null)?et(e,l):pn),n=new n(t,o),e.memoizedState=n.state!==null&&n.state!==void 0?n.state:null,n.updater=vl,e.stateNode=n,n._reactInternals=e,r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=l,e.__reactInternalMemoizedMaskedChildContext=o),n}function ls(e,n,t,r){e=n.state,typeof n.componentWillReceiveProps==\"function\"&&n.componentWillReceiveProps(t,r),typeof n.UNSAFE_componentWillReceiveProps==\"function\"&&n.UNSAFE_componentWillReceiveProps(t,r),n.state!==e&&vl.enqueueReplaceState(n,n.state,null)}function Bo(e,n,t,r){var l=e.stateNode;l.props=t,l.state=e.memoizedState,l.refs=za,Nu(e);var o=n.contextType;typeof o==\"object\"&&o!==null?l.context=ke(o):(o=se(n)?xn:ee.current,l.context=et(e,o)),l.state=e.memoizedState,o=n.getDerivedStateFromProps,typeof o==\"function\"&&(Ho(e,n,o,t),l.state=e.memoizedState),typeof n.getDerivedStateFromProps==\"function\"||typeof l.getSnapshotBeforeUpdate==\"function\"||typeof l.UNSAFE_componentWillMount!=\"function\"&&typeof l.componentWillMount!=\"function\"||(n=l.state,typeof l.componentWillMount==\"function\"&&l.componentWillMount(),typeof l.UNSAFE_componentWillMount==\"function\"&&l.UNSAFE_componentWillMount(),n!==l.state&&vl.enqueueReplaceState(l,l.state,null),el(e,t,l,r),l.state=e.memoizedState),typeof l.componentDidMount==\"function\"&&(e.flags|=4194308)}function ht(e,n,t){if(e=t.ref,e!==null&&typeof e!=\"function\"&&typeof e!=\"object\"){if(t._owner){if(t=t._owner,t){if(t.tag!==1)throw Error(h(309));var r=t.stateNode}if(!r)throw Error(h(147,e));var l=r,o=\"\"+e;return n!==null&&n.ref!==null&&typeof n.ref==\"function\"&&n.ref._stringRef===o?n.ref:(n=function(u){var i=l.refs;i===za&&(i=l.refs={}),u===null?delete i[o]:i[o]=u},n._stringRef=o,n)}if(typeof e!=\"string\")throw Error(h(284));if(!t._owner)throw Error(h(290,e))}return e}function xr(e,n){throw e=Object.prototype.toString.call(n),Error(h(31,e===\"[object Object]\"?\"object with keys {\"+Object.keys(n).join(\", \")+\"}\":e))}function os(e){var n=e._init;return n(e._payload)}function La(e){function n(c,a){if(e){var d=c.deletions;d===null?(c.deletions=[a],c.flags|=16):d.push(a)}}function t(c,a){if(!e)return null;for(;a!==null;)n(c,a),a=a.sibling;return null}function r(c,a){for(c=new Map;a!==null;)a.key!==null?c.set(a.key,a):c.set(a.index,a),a=a.sibling;return c}function l(c,a){return c=fn(c,a),c.index=0,c.sibling=null,c}function o(c,a,d){return c.index=d,e?(d=c.alternate,d!==null?(d=d.index,d<a?(c.flags|=2,a):d):(c.flags|=2,a)):(c.flags|=1048576,a)}function u(c){return e&&c.alternate===null&&(c.flags|=2),c}function i(c,a,d,y){return a===null||a.tag!==6?(a=so(d,c.mode,y),a.return=c,a):(a=l(a,d),a.return=c,a)}function s(c,a,d,y){var E=d.type;return E===Fn?m(c,a,d.props.children,y,d.key):a!==null&&(a.elementType===E||typeof E==\"object\"&&E!==null&&E.$$typeof===Je&&os(E)===a.type)?(y=l(a,d.props),y.ref=ht(c,a,d),y.return=c,y):(y=Ur(d.type,d.key,d.props,null,c.mode,y),y.ref=ht(c,a,d),y.return=c,y)}function f(c,a,d,y){return a===null||a.tag!==4||a.stateNode.containerInfo!==d.containerInfo||a.stateNode.implementation!==d.implementation?(a=ao(d,c.mode,y),a.return=c,a):(a=l(a,d.children||[]),a.return=c,a)}function m(c,a,d,y,E){return a===null||a.tag!==7?(a=Cn(d,c.mode,y,E),a.return=c,a):(a=l(a,d),a.return=c,a)}function v(c,a,d){if(typeof a==\"string\"&&a!==\"\"||typeof a==\"number\")return a=so(\"\"+a,c.mode,d),a.return=c,a;if(typeof a==\"object\"&&a!==null){switch(a.$$typeof){case cr:return d=Ur(a.type,a.key,a.props,null,c.mode,d),d.ref=ht(c,null,a),d.return=c,d;case In:return a=ao(a,c.mode,d),a.return=c,a;case Je:var y=a._init;return v(c,y(a._payload),d)}if(kt(a)||dt(a))return a=Cn(a,c.mode,d,null),a.return=c,a;xr(c,a)}return null}function p(c,a,d,y){var E=a!==null?a.key:null;if(typeof d==\"string\"&&d!==\"\"||typeof d==\"number\")return E!==null?null:i(c,a,\"\"+d,y);if(typeof d==\"object\"&&d!==null){switch(d.$$typeof){case cr:return d.key===E?s(c,a,d,y):null;case In:return d.key===E?f(c,a,d,y):null;case Je:return E=d._init,p(c,a,E(d._payload),y)}if(kt(d)||dt(d))return E!==null?null:m(c,a,d,y,null);xr(c,d)}return null}function g(c,a,d,y,E){if(typeof y==\"string\"&&y!==\"\"||typeof y==\"number\")return c=c.get(d)||null,i(a,c,\"\"+y,E);if(typeof y==\"object\"&&y!==null){switch(y.$$typeof){case cr:return c=c.get(y.key===null?d:y.key)||null,s(a,c,y,E);case In:return c=c.get(y.key===null?d:y.key)||null,f(a,c,y,E);case Je:var _=y._init;return g(c,a,d,_(y._payload),E)}if(kt(y)||dt(y))return c=c.get(d)||null,m(a,c,y,E,null);xr(a,y)}return null}function S(c,a,d,y){for(var E=null,_=null,C=a,x=a=0,$=null;C!==null&&x<d.length;x++){C.index>x?($=C,C=null):$=C.sibling;var z=p(c,C,d[x],y);if(z===null){C===null&&(C=$);break}e&&C&&z.alternate===null&&n(c,C),a=o(z,a,x),_===null?E=z:_.sibling=z,_=z,C=$}if(x===d.length)return t(c,C),M&&gn(c,x),E;if(C===null){for(;x<d.length;x++)C=v(c,d[x],y),C!==null&&(a=o(C,a,x),_===null?E=C:_.sibling=C,_=C);return M&&gn(c,x),E}for(C=r(c,C);x<d.length;x++)$=g(C,c,x,d[x],y),$!==null&&(e&&$.alternate!==null&&C.delete($.key===null?x:$.key),a=o($,a,x),_===null?E=$:_.sibling=$,_=$);return e&&C.forEach(function(Xe){return n(c,Xe)}),M&&gn(c,x),E}function k(c,a,d,y){var E=dt(d);if(typeof E!=\"function\")throw Error(h(150));if(d=E.call(d),d==null)throw Error(h(151));for(var _=E=null,C=a,x=a=0,$=null,z=d.next();C!==null&&!z.done;x++,z=d.next()){C.index>x?($=C,C=null):$=C.sibling;var Xe=p(c,C,z.value,y);if(Xe===null){C===null&&(C=$);break}e&&C&&Xe.alternate===null&&n(c,C),a=o(Xe,a,x),_===null?E=Xe:_.sibling=Xe,_=Xe,C=$}if(z.done)return t(c,C),M&&gn(c,x),E;if(C===null){for(;!z.done;x++,z=d.next())z=v(c,z.value,y),z!==null&&(a=o(z,a,x),_===null?E=z:_.sibling=z,_=z);return M&&gn(c,x),E}for(C=r(c,C);!z.done;x++,z=d.next())z=g(C,c,x,z.value,y),z!==null&&(e&&z.alternate!==null&&C.delete(z.key===null?x:z.key),a=o(z,a,x),_===null?E=z:_.sibling=z,_=z);return e&&C.forEach(function(Vc){return n(c,Vc)}),M&&gn(c,x),E}function V(c,a,d,y){if(typeof d==\"object\"&&d!==null&&d.type===Fn&&d.key===null&&(d=d.props.children),typeof d==\"object\"&&d!==null){switch(d.$$typeof){case cr:e:{for(var E=d.key,_=a;_!==null;){if(_.key===E){if(E=d.type,E===Fn){if(_.tag===7){t(c,_.sibling),a=l(_,d.props.children),a.return=c,c=a;break e}}else if(_.elementType===E||typeof E==\"object\"&&E!==null&&E.$$typeof===Je&&os(E)===_.type){t(c,_.sibling),a=l(_,d.props),a.ref=ht(c,_,d),a.return=c,c=a;break e}t(c,_);break}else n(c,_);_=_.sibling}d.type===Fn?(a=Cn(d.props.children,c.mode,y,d.key),a.return=c,c=a):(y=Ur(d.type,d.key,d.props,null,c.mode,y),y.ref=ht(c,a,d),y.return=c,c=y)}return u(c);case In:e:{for(_=d.key;a!==null;){if(a.key===_)if(a.tag===4&&a.stateNode.containerInfo===d.containerInfo&&a.stateNode.implementation===d.implementation){t(c,a.sibling),a=l(a,d.children||[]),a.return=c,c=a;break e}else{t(c,a);break}else n(c,a);a=a.sibling}a=ao(d,c.mode,y),a.return=c,c=a}return u(c);case Je:return _=d._init,V(c,a,_(d._payload),y)}if(kt(d))return S(c,a,d,y);if(dt(d))return k(c,a,d,y);xr(c,d)}return typeof d==\"string\"&&d!==\"\"||typeof d==\"number\"?(d=\"\"+d,a!==null&&a.tag===6?(t(c,a.sibling),a=l(a,d),a.return=c,c=a):(t(c,a),a=so(d,c.mode,y),a.return=c,c=a),u(c)):t(c,a)}return V}var tt=La(!0),Ra=La(!1),bt={},Fe=vn(bt),$t=vn(bt),Qt=vn(bt);function En(e){if(e===bt)throw Error(h(174));return e}function Pu(e,n){switch(R(Qt,n),R($t,e),R(Fe,bt),e=n.nodeType,e){case 9:case 11:n=(n=n.documentElement)?n.namespaceURI:So(null,\"\");break;default:e=e===8?n.parentNode:n,n=e.namespaceURI||null,e=e.tagName,n=So(n,e)}D(Fe),R(Fe,n)}function rt(){D(Fe),D($t),D(Qt)}function Oa(e){En(Qt.current);var n=En(Fe.current),t=So(n,e.type);n!==t&&(R($t,e),R(Fe,t))}function zu(e){$t.current===e&&(D(Fe),D($t))}var I=vn(0);function nl(e){for(var n=e;n!==null;){if(n.tag===13){var t=n.memoizedState;if(t!==null&&(t=t.dehydrated,t===null||t.data===\"$?\"||t.data===\"$!\"))return n}else if(n.tag===19&&n.memoizedProps.revealOrder!==void 0){if(n.flags&128)return n}else if(n.child!==null){n.child.return=n,n=n.child;continue}if(n===e)break;for(;n.sibling===null;){if(n.return===null||n.return===e)return null;n=n.return}n.sibling.return=n.return,n=n.sibling}return null}var to=[];function Tu(){for(var e=0;e<to.length;e++)to[e]._workInProgressVersionPrimary=null;to.length=0}var Dr=Ye.ReactCurrentDispatcher,ro=Ye.ReactCurrentBatchConfig,Pn=0,F=null,B=null,Q=null,tl=!1,Tt=!1,Kt=0,Od=0;function J(){throw Error(h(321))}function Lu(e,n){if(n===null)return!1;for(var t=0;t<n.length&&t<e.length;t++)if(!Le(e[t],n[t]))return!1;return!0}function Ru(e,n,t,r,l,o){if(Pn=o,F=n,n.memoizedState=null,n.updateQueue=null,n.lanes=0,Dr.current=e===null||e.memoizedState===null?Fd:jd,e=t(r,l),Tt){o=0;do{if(Tt=!1,Kt=0,25<=o)throw Error(h(301));o+=1,Q=B=null,n.updateQueue=null,Dr.current=Ud,e=t(r,l)}while(Tt)}if(Dr.current=rl,n=B!==null&&B.next!==null,Pn=0,Q=B=F=null,tl=!1,n)throw Error(h(300));return e}function Ou(){var e=Kt!==0;return Kt=0,e}function De(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return Q===null?F.memoizedState=Q=e:Q=Q.next=e,Q}function Ee(){if(B===null){var e=F.alternate;e=e!==null?e.memoizedState:null}else e=B.next;var n=Q===null?F.memoizedState:Q.next;if(n!==null)Q=n,B=e;else{if(e===null)throw Error(h(310));B=e,e={memoizedState:B.memoizedState,baseState:B.baseState,baseQueue:B.baseQueue,queue:B.queue,next:null},Q===null?F.memoizedState=Q=e:Q=Q.next=e}return Q}function Yt(e,n){return typeof n==\"function\"?n(e):n}function lo(e){var n=Ee(),t=n.queue;if(t===null)throw Error(h(311));t.lastRenderedReducer=e;var r=B,l=r.baseQueue,o=t.pending;if(o!==null){if(l!==null){var u=l.next;l.next=o.next,o.next=u}r.baseQueue=l=o,t.pending=null}if(l!==null){o=l.next,r=r.baseState;var i=u=null,s=null,f=o;do{var m=f.lane;if((Pn&m)===m)s!==null&&(s=s.next={lane:0,action:f.action,hasEagerState:f.hasEagerState,eagerState:f.eagerState,next:null}),r=f.hasEagerState?f.eagerState:e(r,f.action);else{var v={lane:m,action:f.action,hasEagerState:f.hasEagerState,eagerState:f.eagerState,next:null};s===null?(i=s=v,u=r):s=s.next=v,F.lanes|=m,zn|=m}f=f.next}while(f!==null&&f!==o);s===null?u=r:s.next=i,Le(r,n.memoizedState)||(ue=!0),n.memoizedState=r,n.baseState=u,n.baseQueue=s,t.lastRenderedState=r}if(e=t.interleaved,e!==null){l=e;do o=l.lane,F.lanes|=o,zn|=o,l=l.next;while(l!==e)}else l===null&&(t.lanes=0);return[n.memoizedState,t.dispatch]}function oo(e){var n=Ee(),t=n.queue;if(t===null)throw Error(h(311));t.lastRenderedReducer=e;var r=t.dispatch,l=t.pending,o=n.memoizedState;if(l!==null){t.pending=null;var u=l=l.next;do o=e(o,u.action),u=u.next;while(u!==l);Le(o,n.memoizedState)||(ue=!0),n.memoizedState=o,n.baseQueue===null&&(n.baseState=o),t.lastRenderedState=o}return[o,r]}function Da(){}function Ma(e,n){var t=F,r=Ee(),l=n(),o=!Le(r.memoizedState,l);if(o&&(r.memoizedState=l,ue=!0),r=r.queue,Du(ja.bind(null,t,r,e),[e]),r.getSnapshot!==n||o||Q!==null&&Q.memoizedState.tag&1){if(t.flags|=2048,Xt(9,Fa.bind(null,t,r,l,n),void 0,null),K===null)throw Error(h(349));Pn&30||Ia(t,n,l)}return l}function Ia(e,n,t){e.flags|=16384,e={getSnapshot:n,value:t},n=F.updateQueue,n===null?(n={lastEffect:null,stores:null},F.updateQueue=n,n.stores=[e]):(t=n.stores,t===null?n.stores=[e]:t.push(e))}function Fa(e,n,t,r){n.value=t,n.getSnapshot=r,Ua(n)&&Va(e)}function ja(e,n,t){return t(function(){Ua(n)&&Va(e)})}function Ua(e){var n=e.getSnapshot;e=e.value;try{var t=n();return!Le(e,t)}catch{return!0}}function Va(e){var n=Qe(e,1);n!==null&&Te(n,e,1,-1)}function us(e){var n=De();return typeof e==\"function\"&&(e=e()),n.memoizedState=n.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Yt,lastRenderedState:e},n.queue=e,e=e.dispatch=Id.bind(null,F,e),[n.memoizedState,e]}function Xt(e,n,t,r){return e={tag:e,create:n,destroy:t,deps:r,next:null},n=F.updateQueue,n===null?(n={lastEffect:null,stores:null},F.updateQueue=n,n.lastEffect=e.next=e):(t=n.lastEffect,t===null?n.lastEffect=e.next=e:(r=t.next,t.next=e,e.next=r,n.lastEffect=e)),e}function Aa(){return Ee().memoizedState}function Mr(e,n,t,r){var l=De();F.flags|=e,l.memoizedState=Xt(1|n,t,void 0,r===void 0?null:r)}function hl(e,n,t,r){var l=Ee();r=r===void 0?null:r;var o=void 0;if(B!==null){var u=B.memoizedState;if(o=u.destroy,r!==null&&Lu(r,u.deps)){l.memoizedState=Xt(n,t,o,r);return}}F.flags|=e,l.memoizedState=Xt(1|n,t,o,r)}function is(e,n){return Mr(8390656,8,e,n)}function Du(e,n){return hl(2048,8,e,n)}function Ha(e,n){return hl(4,2,e,n)}function Ba(e,n){return hl(4,4,e,n)}function Wa(e,n){if(typeof n==\"function\")return e=e(),n(e),function(){n(null)};if(n!=null)return e=e(),n.current=e,function(){n.current=null}}function $a(e,n,t){return t=t!=null?t.concat([e]):null,hl(4,4,Wa.bind(null,n,e),t)}function Mu(){}function Qa(e,n){var t=Ee();n=n===void 0?null:n;var r=t.memoizedState;return r!==null&&n!==null&&Lu(n,r[1])?r[0]:(t.memoizedState=[e,n],e)}function Ka(e,n){var t=Ee();n=n===void 0?null:n;var r=t.memoizedState;return r!==null&&n!==null&&Lu(n,r[1])?r[0]:(e=e(),t.memoizedState=[e,n],e)}function Ya(e,n,t){return Pn&21?(Le(t,n)||(t=Zs(),F.lanes|=t,zn|=t,e.baseState=!0),n):(e.baseState&&(e.baseState=!1,ue=!0),e.memoizedState=t)}function Dd(e,n){var t=T;T=t!==0&&4>t?t:4,e(!0);var r=ro.transition;ro.transition={};try{e(!1),n()}finally{T=t,ro.transition=r}}function Xa(){return Ee().memoizedState}function Md(e,n,t){var r=cn(e);if(t={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null},Ga(e))Za(n,t);else if(t=Na(e,n,t,r),t!==null){var l=re();Te(t,e,r,l),Ja(t,n,r)}}function Id(e,n,t){var r=cn(e),l={lane:r,action:t,hasEagerState:!1,eagerState:null,next:null};if(Ga(e))Za(n,l);else{var o=e.alternate;if(e.lanes===0&&(o===null||o.lanes===0)&&(o=n.lastRenderedReducer,o!==null))try{var u=n.lastRenderedState,i=o(u,t);if(l.hasEagerState=!0,l.eagerState=i,Le(i,u)){var s=n.interleaved;s===null?(l.next=l,xu(n)):(l.next=s.next,s.next=l),n.interleaved=l;return}}catch{}finally{}t=Na(e,n,l,r),t!==null&&(l=re(),Te(t,e,r,l),Ja(t,n,r))}}function Ga(e){var n=e.alternate;return e===F||n!==null&&n===F}function Za(e,n){Tt=tl=!0;var t=e.pending;t===null?n.next=n:(n.next=t.next,t.next=n),e.pending=n}function Ja(e,n,t){if(t&4194240){var r=n.lanes;r&=e.pendingLanes,t|=r,n.lanes=t,fu(e,t)}}var rl={readContext:ke,useCallback:J,useContext:J,useEffect:J,useImperativeHandle:J,useInsertionEffect:J,useLayoutEffect:J,useMemo:J,useReducer:J,useRef:J,useState:J,useDebugValue:J,useDeferredValue:J,useTransition:J,useMutableSource:J,useSyncExternalStore:J,useId:J,unstable_isNewReconciler:!1},Fd={readContext:ke,useCallback:function(e,n){return De().memoizedState=[e,n===void 0?null:n],e},useContext:ke,useEffect:is,useImperativeHandle:function(e,n,t){return t=t!=null?t.concat([e]):null,Mr(4194308,4,Wa.bind(null,n,e),t)},useLayoutEffect:function(e,n){return Mr(4194308,4,e,n)},useInsertionEffect:function(e,n){return Mr(4,2,e,n)},useMemo:function(e,n){var t=De();return n=n===void 0?null:n,e=e(),t.memoizedState=[e,n],e},useReducer:function(e,n,t){var r=De();return n=t!==void 0?t(n):n,r.memoizedState=r.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},r.queue=e,e=e.dispatch=Md.bind(null,F,e),[r.memoizedState,e]},useRef:function(e){var n=De();return e={current:e},n.memoizedState=e},useState:us,useDebugValue:Mu,useDeferredValue:function(e){return De().memoizedState=e},useTransition:function(){var e=us(!1),n=e[0];return e=Dd.bind(null,e[1]),De().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,t){var r=F,l=De();if(M){if(t===void 0)throw Error(h(407));t=t()}else{if(t=n(),K===null)throw Error(h(349));Pn&30||Ia(r,n,t)}l.memoizedState=t;var o={value:t,getSnapshot:n};return l.queue=o,is(ja.bind(null,r,o,e),[e]),r.flags|=2048,Xt(9,Fa.bind(null,r,o,t,n),void 0,null),t},useId:function(){var e=De(),n=K.identifierPrefix;if(M){var t=He,r=Ae;t=(r&~(1<<32-ze(r)-1)).toString(32)+t,n=\":\"+n+\"R\"+t,t=Kt++,0<t&&(n+=\"H\"+t.toString(32)),n+=\":\"}else t=Od++,n=\":\"+n+\"r\"+t.toString(32)+\":\";return e.memoizedState=n},unstable_isNewReconciler:!1},jd={readContext:ke,useCallback:Qa,useContext:ke,useEffect:Du,useImperativeHandle:$a,useInsertionEffect:Ha,useLayoutEffect:Ba,useMemo:Ka,useReducer:lo,useRef:Aa,useState:function(){return lo(Yt)},useDebugValue:Mu,useDeferredValue:function(e){var n=Ee();return Ya(n,B.memoizedState,e)},useTransition:function(){var e=lo(Yt)[0],n=Ee().memoizedState;return[e,n]},useMutableSource:Da,useSyncExternalStore:Ma,useId:Xa,unstable_isNewReconciler:!1},Ud={readContext:ke,useCallback:Qa,useContext:ke,useEffect:Du,useImperativeHandle:$a,useInsertionEffect:Ha,useLayoutEffect:Ba,useMemo:Ka,useReducer:oo,useRef:Aa,useState:function(){return oo(Yt)},useDebugValue:Mu,useDeferredValue:function(e){var n=Ee();return B===null?n.memoizedState=e:Ya(n,B.memoizedState,e)},useTransition:function(){var e=oo(Yt)[0],n=Ee().memoizedState;return[e,n]},useMutableSource:Da,useSyncExternalStore:Ma,useId:Xa,unstable_isNewReconciler:!1};function lt(e,n){try{var t=\"\",r=n;do t+=mf(r),r=r.return;while(r);var l=t}catch(o){l=`\nError generating stack: `+o.message+`\n`+o.stack}return{value:e,source:n,stack:l,digest:null}}function uo(e,n,t){return{value:e,source:null,stack:t??null,digest:n??null}}function Wo(e,n){try{console.error(n.value)}catch(t){setTimeout(function(){throw t})}}var Vd=typeof WeakMap==\"function\"?WeakMap:Map;function qa(e,n,t){t=Be(-1,t),t.tag=3,t.payload={element:null};var r=n.value;return t.callback=function(){ol||(ol=!0,bo=r),Wo(e,n)},t}function ba(e,n,t){t=Be(-1,t),t.tag=3;var r=e.type.getDerivedStateFromError;if(typeof r==\"function\"){var l=n.value;t.payload=function(){return r(l)},t.callback=function(){Wo(e,n)}}var o=e.stateNode;return o!==null&&typeof o.componentDidCatch==\"function\"&&(t.callback=function(){Wo(e,n),typeof r!=\"function\"&&(an===null?an=new Set([this]):an.add(this));var u=n.stack;this.componentDidCatch(n.value,{componentStack:u!==null?u:\"\"})}),t}function ss(e,n,t){var r=e.pingCache;if(r===null){r=e.pingCache=new Vd;var l=new Set;r.set(n,l)}else l=r.get(n),l===void 0&&(l=new Set,r.set(n,l));l.has(t)||(l.add(t),e=bd.bind(null,e,n,t),n.then(e,e))}function as(e){do{var n;if((n=e.tag===13)&&(n=e.memoizedState,n=n!==null?n.dehydrated!==null:!0),n)return e;e=e.return}while(e!==null);return null}function cs(e,n,t,r,l){return e.mode&1?(e.flags|=65536,e.lanes=l,e):(e===n?e.flags|=65536:(e.flags|=128,t.flags|=131072,t.flags&=-52805,t.tag===1&&(t.alternate===null?t.tag=17:(n=Be(-1,1),n.tag=2,sn(t,n,1))),t.lanes|=1),e)}var Ad=Ye.ReactCurrentOwner,ue=!1;function te(e,n,t,r){n.child=e===null?Ra(n,null,t,r):tt(n,e.child,t,r)}function fs(e,n,t,r,l){t=t.render;var o=n.ref;return Jn(n,l),r=Ru(e,n,t,r,o,l),t=Ou(),e!==null&&!ue?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~l,Ke(e,n,l)):(M&&t&&wu(n),n.flags|=1,te(e,n,r,l),n.child)}function ds(e,n,t,r,l){if(e===null){var o=t.type;return typeof o==\"function\"&&!Bu(o)&&o.defaultProps===void 0&&t.compare===null&&t.defaultProps===void 0?(n.tag=15,n.type=o,ec(e,n,o,r,l)):(e=Ur(t.type,null,r,n,n.mode,l),e.ref=n.ref,e.return=n,n.child=e)}if(o=e.child,!(e.lanes&l)){var u=o.memoizedProps;if(t=t.compare,t=t!==null?t:At,t(u,r)&&e.ref===n.ref)return Ke(e,n,l)}return n.flags|=1,e=fn(o,r),e.ref=n.ref,e.return=n,n.child=e}function ec(e,n,t,r,l){if(e!==null){var o=e.memoizedProps;if(At(o,r)&&e.ref===n.ref)if(ue=!1,n.pendingProps=r=o,(e.lanes&l)!==0)e.flags&131072&&(ue=!0);else return n.lanes=e.lanes,Ke(e,n,l)}return $o(e,n,t,r,l)}function nc(e,n,t){var r=n.pendingProps,l=r.children,o=e!==null?e.memoizedState:null;if(r.mode===\"hidden\")if(!(n.mode&1))n.memoizedState={baseLanes:0,cachePool:null,transitions:null},R(Kn,ce),ce|=t;else{if(!(t&1073741824))return e=o!==null?o.baseLanes|t:t,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,R(Kn,ce),ce|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=o!==null?o.baseLanes:t,R(Kn,ce),ce|=r}else o!==null?(r=o.baseLanes|t,n.memoizedState=null):r=t,R(Kn,ce),ce|=r;return te(e,n,l,t),n.child}function tc(e,n){var t=n.ref;(e===null&&t!==null||e!==null&&e.ref!==t)&&(n.flags|=512,n.flags|=2097152)}function $o(e,n,t,r,l){var o=se(t)?xn:ee.current;return o=et(n,o),Jn(n,l),t=Ru(e,n,t,r,o,l),r=Ou(),e!==null&&!ue?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~l,Ke(e,n,l)):(M&&r&&wu(n),n.flags|=1,te(e,n,t,l),n.child)}function ps(e,n,t,r,l){if(se(t)){var o=!0;Gr(n)}else o=!1;if(Jn(n,l),n.stateNode===null)Ir(e,n),Ta(n,t,r),Bo(n,t,r,l),r=!0;else if(e===null){var u=n.stateNode,i=n.memoizedProps;u.props=i;var s=u.context,f=t.contextType;typeof f==\"object\"&&f!==null?f=ke(f):(f=se(t)?xn:ee.current,f=et(n,f));var m=t.getDerivedStateFromProps,v=typeof m==\"function\"||typeof u.getSnapshotBeforeUpdate==\"function\";v||typeof u.UNSAFE_componentWillReceiveProps!=\"function\"&&typeof u.componentWillReceiveProps!=\"function\"||(i!==r||s!==f)&&ls(n,u,r,f),qe=!1;var p=n.memoizedState;u.state=p,el(n,r,u,l),s=n.memoizedState,i!==r||p!==s||ie.current||qe?(typeof m==\"function\"&&(Ho(n,t,m,r),s=n.memoizedState),(i=qe||rs(n,t,i,r,p,s,f))?(v||typeof u.UNSAFE_componentWillMount!=\"function\"&&typeof u.componentWillMount!=\"function\"||(typeof u.componentWillMount==\"function\"&&u.componentWillMount(),typeof u.UNSAFE_componentWillMount==\"function\"&&u.UNSAFE_componentWillMount()),typeof u.componentDidMount==\"function\"&&(n.flags|=4194308)):(typeof u.componentDidMount==\"function\"&&(n.flags|=4194308),n.memoizedProps=r,n.memoizedState=s),u.props=r,u.state=s,u.context=f,r=i):(typeof u.componentDidMount==\"function\"&&(n.flags|=4194308),r=!1)}else{u=n.stateNode,Pa(e,n),i=n.memoizedProps,f=n.type===n.elementType?i:xe(n.type,i),u.props=f,v=n.pendingProps,p=u.context,s=t.contextType,typeof s==\"object\"&&s!==null?s=ke(s):(s=se(t)?xn:ee.current,s=et(n,s));var g=t.getDerivedStateFromProps;(m=typeof g==\"function\"||typeof u.getSnapshotBeforeUpdate==\"function\")||typeof u.UNSAFE_componentWillReceiveProps!=\"function\"&&typeof u.componentWillReceiveProps!=\"function\"||(i!==v||p!==s)&&ls(n,u,r,s),qe=!1,p=n.memoizedState,u.state=p,el(n,r,u,l);var S=n.memoizedState;i!==v||p!==S||ie.current||qe?(typeof g==\"function\"&&(Ho(n,t,g,r),S=n.memoizedState),(f=qe||rs(n,t,f,r,p,S,s)||!1)?(m||typeof u.UNSAFE_componentWillUpdate!=\"function\"&&typeof u.componentWillUpdate!=\"function\"||(typeof u.componentWillUpdate==\"function\"&&u.componentWillUpdate(r,S,s),typeof u.UNSAFE_componentWillUpdate==\"function\"&&u.UNSAFE_componentWillUpdate(r,S,s)),typeof u.componentDidUpdate==\"function\"&&(n.flags|=4),typeof u.getSnapshotBeforeUpdate==\"function\"&&(n.flags|=1024)):(typeof u.componentDidUpdate!=\"function\"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=4),typeof u.getSnapshotBeforeUpdate!=\"function\"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=1024),n.memoizedProps=r,n.memoizedState=S),u.props=r,u.state=S,u.context=s,r=f):(typeof u.componentDidUpdate!=\"function\"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=4),typeof u.getSnapshotBeforeUpdate!=\"function\"||i===e.memoizedProps&&p===e.memoizedState||(n.flags|=1024),r=!1)}return Qo(e,n,t,r,o,l)}function Qo(e,n,t,r,l,o){tc(e,n);var u=(n.flags&128)!==0;if(!r&&!u)return l&&qi(n,t,!1),Ke(e,n,o);r=n.stateNode,Ad.current=n;var i=u&&typeof t.getDerivedStateFromError!=\"function\"?null:r.render();return n.flags|=1,e!==null&&u?(n.child=tt(n,e.child,null,o),n.child=tt(n,null,i,o)):te(e,n,i,o),n.memoizedState=r.state,l&&qi(n,t,!0),n.child}function rc(e){var n=e.stateNode;n.pendingContext?Ji(e,n.pendingContext,n.pendingContext!==n.context):n.context&&Ji(e,n.context,!1),Pu(e,n.containerInfo)}function ms(e,n,t,r,l){return nt(),ku(l),n.flags|=256,te(e,n,t,r),n.child}var Ko={dehydrated:null,treeContext:null,retryLane:0};function Yo(e){return{baseLanes:e,cachePool:null,transitions:null}}function lc(e,n,t){var r=n.pendingProps,l=I.current,o=!1,u=(n.flags&128)!==0,i;if((i=u)||(i=e!==null&&e.memoizedState===null?!1:(l&2)!==0),i?(o=!0,n.flags&=-129):(e===null||e.memoizedState!==null)&&(l|=1),R(I,l&1),e===null)return Vo(n),e=n.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?(n.mode&1?e.data===\"$!\"?n.lanes=8:n.lanes=1073741824:n.lanes=1,null):(u=r.children,e=r.fallback,o?(r=n.mode,o=n.child,u={mode:\"hidden\",children:u},!(r&1)&&o!==null?(o.childLanes=0,o.pendingProps=u):o=wl(u,r,0,null),e=Cn(e,r,t,null),o.return=n,e.return=n,o.sibling=e,n.child=o,n.child.memoizedState=Yo(t),n.memoizedState=Ko,e):Iu(n,u));if(l=e.memoizedState,l!==null&&(i=l.dehydrated,i!==null))return Hd(e,n,u,r,i,l,t);if(o){o=r.fallback,u=n.mode,l=e.child,i=l.sibling;var s={mode:\"hidden\",children:r.children};return!(u&1)&&n.child!==l?(r=n.child,r.childLanes=0,r.pendingProps=s,n.deletions=null):(r=fn(l,s),r.subtreeFlags=l.subtreeFlags&14680064),i!==null?o=fn(i,o):(o=Cn(o,u,t,null),o.flags|=2),o.return=n,r.return=n,r.sibling=o,n.child=r,r=o,o=n.child,u=e.child.memoizedState,u=u===null?Yo(t):{baseLanes:u.baseLanes|t,cachePool:null,transitions:u.transitions},o.memoizedState=u,o.childLanes=e.childLanes&~t,n.memoizedState=Ko,r}return o=e.child,e=o.sibling,r=fn(o,{mode:\"visible\",children:r.children}),!(n.mode&1)&&(r.lanes=t),r.return=n,r.sibling=null,e!==null&&(t=n.deletions,t===null?(n.deletions=[e],n.flags|=16):t.push(e)),n.child=r,n.memoizedState=null,r}function Iu(e,n){return n=wl({mode:\"visible\",children:n},e.mode,0,null),n.return=e,e.child=n}function Nr(e,n,t,r){return r!==null&&ku(r),tt(n,e.child,null,t),e=Iu(n,n.pendingProps.children),e.flags|=2,n.memoizedState=null,e}function Hd(e,n,t,r,l,o,u){if(t)return n.flags&256?(n.flags&=-257,r=uo(Error(h(422))),Nr(e,n,u,r)):n.memoizedState!==null?(n.child=e.child,n.flags|=128,null):(o=r.fallback,l=n.mode,r=wl({mode:\"visible\",children:r.children},l,0,null),o=Cn(o,l,u,null),o.flags|=2,r.return=n,o.return=n,r.sibling=o,n.child=r,n.mode&1&&tt(n,e.child,null,u),n.child.memoizedState=Yo(u),n.memoizedState=Ko,o);if(!(n.mode&1))return Nr(e,n,u,null);if(l.data===\"$!\"){if(r=l.nextSibling&&l.nextSibling.dataset,r)var i=r.dgst;return r=i,o=Error(h(419)),r=uo(o,r,void 0),Nr(e,n,u,r)}if(i=(u&e.childLanes)!==0,ue||i){if(r=K,r!==null){switch(u&-u){case 4:l=2;break;case 16:l=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:l=32;break;case 536870912:l=268435456;break;default:l=0}l=l&(r.suspendedLanes|u)?0:l,l!==0&&l!==o.retryLane&&(o.retryLane=l,Qe(e,l),Te(r,e,l,-1))}return Hu(),r=uo(Error(h(421))),Nr(e,n,u,r)}return l.data===\"$?\"?(n.flags|=128,n.child=e.child,n=ep.bind(null,e),l._reactRetry=n,null):(e=o.treeContext,fe=un(l.nextSibling),de=n,M=!0,Pe=null,e!==null&&(ye[ge++]=Ae,ye[ge++]=He,ye[ge++]=Nn,Ae=e.id,He=e.overflow,Nn=n),n=Iu(n,r.children),n.flags|=4096,n)}function vs(e,n,t){e.lanes|=n;var r=e.alternate;r!==null&&(r.lanes|=n),Ao(e.return,n,t)}function io(e,n,t,r,l){var o=e.memoizedState;o===null?e.memoizedState={isBackwards:n,rendering:null,renderingStartTime:0,last:r,tail:t,tailMode:l}:(o.isBackwards=n,o.rendering=null,o.renderingStartTime=0,o.last=r,o.tail=t,o.tailMode=l)}function oc(e,n,t){var r=n.pendingProps,l=r.revealOrder,o=r.tail;if(te(e,n,r.children,t),r=I.current,r&2)r=r&1|2,n.flags|=128;else{if(e!==null&&e.flags&128)e:for(e=n.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&vs(e,t,n);else if(e.tag===19)vs(e,t,n);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===n)break e;for(;e.sibling===null;){if(e.return===null||e.return===n)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(R(I,r),!(n.mode&1))n.memoizedState=null;else switch(l){case\"forwards\":for(t=n.child,l=null;t!==null;)e=t.alternate,e!==null&&nl(e)===null&&(l=t),t=t.sibling;t=l,t===null?(l=n.child,n.child=null):(l=t.sibling,t.sibling=null),io(n,!1,l,t,o);break;case\"backwards\":for(t=null,l=n.child,n.child=null;l!==null;){if(e=l.alternate,e!==null&&nl(e)===null){n.child=l;break}e=l.sibling,l.sibling=t,t=l,l=e}io(n,!0,t,null,o);break;case\"together\":io(n,!1,null,null,void 0);break;default:n.memoizedState=null}return n.child}function Ir(e,n){!(n.mode&1)&&e!==null&&(e.alternate=null,n.alternate=null,n.flags|=2)}function Ke(e,n,t){if(e!==null&&(n.dependencies=e.dependencies),zn|=n.lanes,!(t&n.childLanes))return null;if(e!==null&&n.child!==e.child)throw Error(h(153));if(n.child!==null){for(e=n.child,t=fn(e,e.pendingProps),n.child=t,t.return=n;e.sibling!==null;)e=e.sibling,t=t.sibling=fn(e,e.pendingProps),t.return=n;t.sibling=null}return n.child}function Bd(e,n,t){switch(n.tag){case 3:rc(n),nt();break;case 5:Oa(n);break;case 1:se(n.type)&&Gr(n);break;case 4:Pu(n,n.stateNode.containerInfo);break;case 10:var r=n.type._context,l=n.memoizedProps.value;R(qr,r._currentValue),r._currentValue=l;break;case 13:if(r=n.memoizedState,r!==null)return r.dehydrated!==null?(R(I,I.current&1),n.flags|=128,null):t&n.child.childLanes?lc(e,n,t):(R(I,I.current&1),e=Ke(e,n,t),e!==null?e.sibling:null);R(I,I.current&1);break;case 19:if(r=(t&n.childLanes)!==0,e.flags&128){if(r)return oc(e,n,t);n.flags|=128}if(l=n.memoizedState,l!==null&&(l.rendering=null,l.tail=null,l.lastEffect=null),R(I,I.current),r)break;return null;case 22:case 23:return n.lanes=0,nc(e,n,t)}return Ke(e,n,t)}var uc,Xo,ic,sc;uc=function(e,n){for(var t=n.child;t!==null;){if(t.tag===5||t.tag===6)e.appendChild(t.stateNode);else if(t.tag!==4&&t.child!==null){t.child.return=t,t=t.child;continue}if(t===n)break;for(;t.sibling===null;){if(t.return===null||t.return===n)return;t=t.return}t.sibling.return=t.return,t=t.sibling}};Xo=function(){};ic=function(e,n,t,r){var l=e.memoizedProps;if(l!==r){e=n.stateNode,En(Fe.current);var o=null;switch(t){case\"input\":l=ho(e,l),r=ho(e,r),o=[];break;case\"select\":l=j({},l,{value:void 0}),r=j({},r,{value:void 0}),o=[];break;case\"textarea\":l=wo(e,l),r=wo(e,r),o=[];break;default:typeof l.onClick!=\"function\"&&typeof r.onClick==\"function\"&&(e.onclick=Yr)}ko(t,r);var u;t=null;for(f in l)if(!r.hasOwnProperty(f)&&l.hasOwnProperty(f)&&l[f]!=null)if(f===\"style\"){var i=l[f];for(u in i)i.hasOwnProperty(u)&&(t||(t={}),t[u]=\"\")}else f!==\"dangerouslySetInnerHTML\"&&f!==\"children\"&&f!==\"suppressContentEditableWarning\"&&f!==\"suppressHydrationWarning\"&&f!==\"autoFocus\"&&(Dt.hasOwnProperty(f)?o||(o=[]):(o=o||[]).push(f,null));for(f in r){var s=r[f];if(i=l?.[f],r.hasOwnProperty(f)&&s!==i&&(s!=null||i!=null))if(f===\"style\")if(i){for(u in i)!i.hasOwnProperty(u)||s&&s.hasOwnProperty(u)||(t||(t={}),t[u]=\"\");for(u in s)s.hasOwnProperty(u)&&i[u]!==s[u]&&(t||(t={}),t[u]=s[u])}else t||(o||(o=[]),o.push(f,t)),t=s;else f===\"dangerouslySetInnerHTML\"?(s=s?s.__html:void 0,i=i?i.__html:void 0,s!=null&&i!==s&&(o=o||[]).push(f,s)):f===\"children\"?typeof s!=\"string\"&&typeof s!=\"number\"||(o=o||[]).push(f,\"\"+s):f!==\"suppressContentEditableWarning\"&&f!==\"suppressHydrationWarning\"&&(Dt.hasOwnProperty(f)?(s!=null&&f===\"onScroll\"&&O(\"scroll\",e),o||i===s||(o=[])):(o=o||[]).push(f,s))}t&&(o=o||[]).push(\"style\",t);var f=o;(n.updateQueue=f)&&(n.flags|=4)}};sc=function(e,n,t,r){t!==r&&(n.flags|=4)};function yt(e,n){if(!M)switch(e.tailMode){case\"hidden\":n=e.tail;for(var t=null;n!==null;)n.alternate!==null&&(t=n),n=n.sibling;t===null?e.tail=null:t.sibling=null;break;case\"collapsed\":t=e.tail;for(var r=null;t!==null;)t.alternate!==null&&(r=t),t=t.sibling;r===null?n||e.tail===null?e.tail=null:e.tail.sibling=null:r.sibling=null}}function q(e){var n=e.alternate!==null&&e.alternate.child===e.child,t=0,r=0;if(n)for(var l=e.child;l!==null;)t|=l.lanes|l.childLanes,r|=l.subtreeFlags&14680064,r|=l.flags&14680064,l.return=e,l=l.sibling;else for(l=e.child;l!==null;)t|=l.lanes|l.childLanes,r|=l.subtreeFlags,r|=l.flags,l.return=e,l=l.sibling;return e.subtreeFlags|=r,e.childLanes=t,n}function Wd(e,n,t){var r=n.pendingProps;switch(Su(n),n.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return q(n),null;case 1:return se(n.type)&&Xr(),q(n),null;case 3:return r=n.stateNode,rt(),D(ie),D(ee),Tu(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),(e===null||e.child===null)&&(Cr(n)?n.flags|=4:e===null||e.memoizedState.isDehydrated&&!(n.flags&256)||(n.flags|=1024,Pe!==null&&(tu(Pe),Pe=null))),Xo(e,n),q(n),null;case 5:zu(n);var l=En(Qt.current);if(t=n.type,e!==null&&n.stateNode!=null)ic(e,n,t,r,l),e.ref!==n.ref&&(n.flags|=512,n.flags|=2097152);else{if(!r){if(n.stateNode===null)throw Error(h(166));return q(n),null}if(e=En(Fe.current),Cr(n)){r=n.stateNode,t=n.type;var o=n.memoizedProps;switch(r[Me]=n,r[Wt]=o,e=(n.mode&1)!==0,t){case\"dialog\":O(\"cancel\",r),O(\"close\",r);break;case\"iframe\":case\"object\":case\"embed\":O(\"load\",r);break;case\"video\":case\"audio\":for(l=0;l<_t.length;l++)O(_t[l],r);break;case\"source\":O(\"error\",r);break;case\"img\":case\"image\":case\"link\":O(\"error\",r),O(\"load\",r);break;case\"details\":O(\"toggle\",r);break;case\"input\":_i(r,o),O(\"invalid\",r);break;case\"select\":r._wrapperState={wasMultiple:!!o.multiple},O(\"invalid\",r);break;case\"textarea\":xi(r,o),O(\"invalid\",r)}ko(t,o),l=null;for(var u in o)if(o.hasOwnProperty(u)){var i=o[u];u===\"children\"?typeof i==\"string\"?r.textContent!==i&&(o.suppressHydrationWarning!==!0&&_r(r.textContent,i,e),l=[\"children\",i]):typeof i==\"number\"&&r.textContent!==\"\"+i&&(o.suppressHydrationWarning!==!0&&_r(r.textContent,i,e),l=[\"children\",\"\"+i]):Dt.hasOwnProperty(u)&&i!=null&&u===\"onScroll\"&&O(\"scroll\",r)}switch(t){case\"input\":fr(r),Ci(r,o,!0);break;case\"textarea\":fr(r),Ni(r);break;case\"select\":case\"option\":break;default:typeof o.onClick==\"function\"&&(r.onclick=Yr)}r=l,n.updateQueue=r,r!==null&&(n.flags|=4)}else{u=l.nodeType===9?l:l.ownerDocument,e===\"http://www.w3.org/1999/xhtml\"&&(e=Is(t)),e===\"http://www.w3.org/1999/xhtml\"?t===\"script\"?(e=u.createElement(\"div\"),e.innerHTML=\"<script><\\/script>\",e=e.removeChild(e.firstChild)):typeof r.is==\"string\"?e=u.createElement(t,{is:r.is}):(e=u.createElement(t),t===\"select\"&&(u=e,r.multiple?u.multiple=!0:r.size&&(u.size=r.size))):e=u.createElementNS(e,t),e[Me]=n,e[Wt]=r,uc(e,n,!1,!1),n.stateNode=e;e:{switch(u=Eo(t,r),t){case\"dialog\":O(\"cancel\",e),O(\"close\",e),l=r;break;case\"iframe\":case\"object\":case\"embed\":O(\"load\",e),l=r;break;case\"video\":case\"audio\":for(l=0;l<_t.length;l++)O(_t[l],e);l=r;break;case\"source\":O(\"error\",e),l=r;break;case\"img\":case\"image\":case\"link\":O(\"error\",e),O(\"load\",e),l=r;break;case\"details\":O(\"toggle\",e),l=r;break;case\"input\":_i(e,r),l=ho(e,r),O(\"invalid\",e);break;case\"option\":l=r;break;case\"select\":e._wrapperState={wasMultiple:!!r.multiple},l=j({},r,{value:void 0}),O(\"invalid\",e);break;case\"textarea\":xi(e,r),l=wo(e,r),O(\"invalid\",e);break;default:l=r}ko(t,l),i=l;for(o in i)if(i.hasOwnProperty(o)){var s=i[o];o===\"style\"?Us(e,s):o===\"dangerouslySetInnerHTML\"?(s=s?s.__html:void 0,s!=null&&Fs(e,s)):o===\"children\"?typeof s==\"string\"?(t!==\"textarea\"||s!==\"\")&&Mt(e,s):typeof s==\"number\"&&Mt(e,\"\"+s):o!==\"suppressContentEditableWarning\"&&o!==\"suppressHydrationWarning\"&&o!==\"autoFocus\"&&(Dt.hasOwnProperty(o)?s!=null&&o===\"onScroll\"&&O(\"scroll\",e):s!=null&&ou(e,o,s,u))}switch(t){case\"input\":fr(e),Ci(e,r,!1);break;case\"textarea\":fr(e),Ni(e);break;case\"option\":r.value!=null&&e.setAttribute(\"value\",\"\"+dn(r.value));break;case\"select\":e.multiple=!!r.multiple,o=r.value,o!=null?Yn(e,!!r.multiple,o,!1):r.defaultValue!=null&&Yn(e,!!r.multiple,r.defaultValue,!0);break;default:typeof l.onClick==\"function\"&&(e.onclick=Yr)}switch(t){case\"button\":case\"input\":case\"select\":case\"textarea\":r=!!r.autoFocus;break e;case\"img\":r=!0;break e;default:r=!1}}r&&(n.flags|=4)}n.ref!==null&&(n.flags|=512,n.flags|=2097152)}return q(n),null;case 6:if(e&&n.stateNode!=null)sc(e,n,e.memoizedProps,r);else{if(typeof r!=\"string\"&&n.stateNode===null)throw Error(h(166));if(t=En(Qt.current),En(Fe.current),Cr(n)){if(r=n.stateNode,t=n.memoizedProps,r[Me]=n,(o=r.nodeValue!==t)&&(e=de,e!==null))switch(e.tag){case 3:_r(r.nodeValue,t,(e.mode&1)!==0);break;case 5:e.memoizedProps.suppressHydrationWarning!==!0&&_r(r.nodeValue,t,(e.mode&1)!==0)}o&&(n.flags|=4)}else r=(t.nodeType===9?t:t.ownerDocument).createTextNode(r),r[Me]=n,n.stateNode=r}return q(n),null;case 13:if(D(I),r=n.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(M&&fe!==null&&n.mode&1&&!(n.flags&128))xa(),nt(),n.flags|=98560,o=!1;else if(o=Cr(n),r!==null&&r.dehydrated!==null){if(e===null){if(!o)throw Error(h(318));if(o=n.memoizedState,o=o!==null?o.dehydrated:null,!o)throw Error(h(317));o[Me]=n}else nt(),!(n.flags&128)&&(n.memoizedState=null),n.flags|=4;q(n),o=!1}else Pe!==null&&(tu(Pe),Pe=null),o=!0;if(!o)return n.flags&65536?n:null}return n.flags&128?(n.lanes=t,n):(r=r!==null,r!==(e!==null&&e.memoizedState!==null)&&r&&(n.child.flags|=8192,n.mode&1&&(e===null||I.current&1?W===0&&(W=3):Hu())),n.updateQueue!==null&&(n.flags|=4),q(n),null);case 4:return rt(),Xo(e,n),e===null&&Ht(n.stateNode.containerInfo),q(n),null;case 10:return Cu(n.type._context),q(n),null;case 17:return se(n.type)&&Xr(),q(n),null;case 19:if(D(I),o=n.memoizedState,o===null)return q(n),null;if(r=(n.flags&128)!==0,u=o.rendering,u===null)if(r)yt(o,!1);else{if(W!==0||e!==null&&e.flags&128)for(e=n.child;e!==null;){if(u=nl(e),u!==null){for(n.flags|=128,yt(o,!1),r=u.updateQueue,r!==null&&(n.updateQueue=r,n.flags|=4),n.subtreeFlags=0,r=t,t=n.child;t!==null;)o=t,e=r,o.flags&=14680066,u=o.alternate,u===null?(o.childLanes=0,o.lanes=e,o.child=null,o.subtreeFlags=0,o.memoizedProps=null,o.memoizedState=null,o.updateQueue=null,o.dependencies=null,o.stateNode=null):(o.childLanes=u.childLanes,o.lanes=u.lanes,o.child=u.child,o.subtreeFlags=0,o.deletions=null,o.memoizedProps=u.memoizedProps,o.memoizedState=u.memoizedState,o.updateQueue=u.updateQueue,o.type=u.type,e=u.dependencies,o.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),t=t.sibling;return R(I,I.current&1|2),n.child}e=e.sibling}o.tail!==null&&A()>ot&&(n.flags|=128,r=!0,yt(o,!1),n.lanes=4194304)}else{if(!r)if(e=nl(u),e!==null){if(n.flags|=128,r=!0,t=e.updateQueue,t!==null&&(n.updateQueue=t,n.flags|=4),yt(o,!0),o.tail===null&&o.tailMode===\"hidden\"&&!u.alternate&&!M)return q(n),null}else 2*A()-o.renderingStartTime>ot&&t!==1073741824&&(n.flags|=128,r=!0,yt(o,!1),n.lanes=4194304);o.isBackwards?(u.sibling=n.child,n.child=u):(t=o.last,t!==null?t.sibling=u:n.child=u,o.last=u)}return o.tail!==null?(n=o.tail,o.rendering=n,o.tail=n.sibling,o.renderingStartTime=A(),n.sibling=null,t=I.current,R(I,r?t&1|2:t&1),n):(q(n),null);case 22:case 23:return Au(),r=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(n.flags|=8192),r&&n.mode&1?ce&1073741824&&(q(n),n.subtreeFlags&6&&(n.flags|=8192)):q(n),null;case 24:return null;case 25:return null}throw Error(h(156,n.tag))}function $d(e,n){switch(Su(n),n.tag){case 1:return se(n.type)&&Xr(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return rt(),D(ie),D(ee),Tu(),e=n.flags,e&65536&&!(e&128)?(n.flags=e&-65537|128,n):null;case 5:return zu(n),null;case 13:if(D(I),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(h(340));nt()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return D(I),null;case 4:return rt(),null;case 10:return Cu(n.type._context),null;case 22:case 23:return Au(),null;case 24:return null;default:return null}}var Pr=!1,b=!1,Qd=typeof WeakSet==\"function\"?WeakSet:Set,w=null;function Qn(e,n){var t=e.ref;if(t!==null)if(typeof t==\"function\")try{t(null)}catch(r){U(e,n,r)}else t.current=null}function Go(e,n,t){try{t()}catch(r){U(e,n,r)}}var hs=!1;function Kd(e,n){if(Oo=$r,e=da(),gu(e)){if(\"selectionStart\"in e)var t={start:e.selectionStart,end:e.selectionEnd};else e:{t=(t=e.ownerDocument)&&t.defaultView||window;var r=t.getSelection&&t.getSelection();if(r&&r.rangeCount!==0){t=r.anchorNode;var l=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{t.nodeType,o.nodeType}catch{t=null;break e}var u=0,i=-1,s=-1,f=0,m=0,v=e,p=null;n:for(;;){for(var g;v!==t||l!==0&&v.nodeType!==3||(i=u+l),v!==o||r!==0&&v.nodeType!==3||(s=u+r),v.nodeType===3&&(u+=v.nodeValue.length),(g=v.firstChild)!==null;)p=v,v=g;for(;;){if(v===e)break n;if(p===t&&++f===l&&(i=u),p===o&&++m===r&&(s=u),(g=v.nextSibling)!==null)break;v=p,p=v.parentNode}v=g}t=i===-1||s===-1?null:{start:i,end:s}}else t=null}t=t||{start:0,end:0}}else t=null;for(Do={focusedElem:e,selectionRange:t},$r=!1,w=n;w!==null;)if(n=w,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,w=e;else for(;w!==null;){n=w;try{var S=n.alternate;if(n.flags&1024)switch(n.tag){case 0:case 11:case 15:break;case 1:if(S!==null){var k=S.memoizedProps,V=S.memoizedState,c=n.stateNode,a=c.getSnapshotBeforeUpdate(n.elementType===n.type?k:xe(n.type,k),V);c.__reactInternalSnapshotBeforeUpdate=a}break;case 3:var d=n.stateNode.containerInfo;d.nodeType===1?d.textContent=\"\":d.nodeType===9&&d.documentElement&&d.removeChild(d.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(h(163))}}catch(y){U(n,n.return,y)}if(e=n.sibling,e!==null){e.return=n.return,w=e;break}w=n.return}return S=hs,hs=!1,S}function Lt(e,n,t){var r=n.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var l=r=r.next;do{if((l.tag&e)===e){var o=l.destroy;l.destroy=void 0,o!==void 0&&Go(n,t,o)}l=l.next}while(l!==r)}}function yl(e,n){if(n=n.updateQueue,n=n!==null?n.lastEffect:null,n!==null){var t=n=n.next;do{if((t.tag&e)===e){var r=t.create;t.destroy=r()}t=t.next}while(t!==n)}}function Zo(e){var n=e.ref;if(n!==null){var t=e.stateNode;switch(e.tag){case 5:e=t;break;default:e=t}typeof n==\"function\"?n(e):n.current=e}}function ac(e){var n=e.alternate;n!==null&&(e.alternate=null,ac(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[Me],delete n[Wt],delete n[Fo],delete n[zd],delete n[Td])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function cc(e){return e.tag===5||e.tag===3||e.tag===4}function ys(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||cc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Jo(e,n,t){var r=e.tag;if(r===5||r===6)e=e.stateNode,n?t.nodeType===8?t.parentNode.insertBefore(e,n):t.insertBefore(e,n):(t.nodeType===8?(n=t.parentNode,n.insertBefore(e,t)):(n=t,n.appendChild(e)),t=t._reactRootContainer,t!=null||n.onclick!==null||(n.onclick=Yr));else if(r!==4&&(e=e.child,e!==null))for(Jo(e,n,t),e=e.sibling;e!==null;)Jo(e,n,t),e=e.sibling}function qo(e,n,t){var r=e.tag;if(r===5||r===6)e=e.stateNode,n?t.insertBefore(e,n):t.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(qo(e,n,t),e=e.sibling;e!==null;)qo(e,n,t),e=e.sibling}var Y=null,Ne=!1;function Ze(e,n,t){for(t=t.child;t!==null;)fc(e,n,t),t=t.sibling}function fc(e,n,t){if(Ie&&typeof Ie.onCommitFiberUnmount==\"function\")try{Ie.onCommitFiberUnmount(al,t)}catch{}switch(t.tag){case 5:b||Qn(t,n);case 6:var r=Y,l=Ne;Y=null,Ze(e,n,t),Y=r,Ne=l,Y!==null&&(Ne?(e=Y,t=t.stateNode,e.nodeType===8?e.parentNode.removeChild(t):e.removeChild(t)):Y.removeChild(t.stateNode));break;case 18:Y!==null&&(Ne?(e=Y,t=t.stateNode,e.nodeType===8?eo(e.parentNode,t):e.nodeType===1&&eo(e,t),Ut(e)):eo(Y,t.stateNode));break;case 4:r=Y,l=Ne,Y=t.stateNode.containerInfo,Ne=!0,Ze(e,n,t),Y=r,Ne=l;break;case 0:case 11:case 14:case 15:if(!b&&(r=t.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){l=r=r.next;do{var o=l,u=o.destroy;o=o.tag,u!==void 0&&(o&2||o&4)&&Go(t,n,u),l=l.next}while(l!==r)}Ze(e,n,t);break;case 1:if(!b&&(Qn(t,n),r=t.stateNode,typeof r.componentWillUnmount==\"function\"))try{r.props=t.memoizedProps,r.state=t.memoizedState,r.componentWillUnmount()}catch(i){U(t,n,i)}Ze(e,n,t);break;case 21:Ze(e,n,t);break;case 22:t.mode&1?(b=(r=b)||t.memoizedState!==null,Ze(e,n,t),b=r):Ze(e,n,t);break;default:Ze(e,n,t)}}function gs(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var t=e.stateNode;t===null&&(t=e.stateNode=new Qd),n.forEach(function(r){var l=np.bind(null,e,r);t.has(r)||(t.add(r),r.then(l,l))})}}function Ce(e,n){var t=n.deletions;if(t!==null)for(var r=0;r<t.length;r++){var l=t[r];try{var o=e,u=n,i=u;e:for(;i!==null;){switch(i.tag){case 5:Y=i.stateNode,Ne=!1;break e;case 3:Y=i.stateNode.containerInfo,Ne=!0;break e;case 4:Y=i.stateNode.containerInfo,Ne=!0;break e}i=i.return}if(Y===null)throw Error(h(160));fc(o,u,l),Y=null,Ne=!1;var s=l.alternate;s!==null&&(s.return=null),l.return=null}catch(f){U(l,n,f)}}if(n.subtreeFlags&12854)for(n=n.child;n!==null;)dc(n,e),n=n.sibling}function dc(e,n){var t=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(Ce(n,e),Oe(e),r&4){try{Lt(3,e,e.return),yl(3,e)}catch(k){U(e,e.return,k)}try{Lt(5,e,e.return)}catch(k){U(e,e.return,k)}}break;case 1:Ce(n,e),Oe(e),r&512&&t!==null&&Qn(t,t.return);break;case 5:if(Ce(n,e),Oe(e),r&512&&t!==null&&Qn(t,t.return),e.flags&32){var l=e.stateNode;try{Mt(l,\"\")}catch(k){U(e,e.return,k)}}if(r&4&&(l=e.stateNode,l!=null)){var o=e.memoizedProps,u=t!==null?t.memoizedProps:o,i=e.type,s=e.updateQueue;if(e.updateQueue=null,s!==null)try{i===\"input\"&&o.type===\"radio\"&&o.name!=null&&Ds(l,o),Eo(i,u);var f=Eo(i,o);for(u=0;u<s.length;u+=2){var m=s[u],v=s[u+1];m===\"style\"?Us(l,v):m===\"dangerouslySetInnerHTML\"?Fs(l,v):m===\"children\"?Mt(l,v):ou(l,m,v,f)}switch(i){case\"input\":yo(l,o);break;case\"textarea\":Ms(l,o);break;case\"select\":var p=l._wrapperState.wasMultiple;l._wrapperState.wasMultiple=!!o.multiple;var g=o.value;g!=null?Yn(l,!!o.multiple,g,!1):p!==!!o.multiple&&(o.defaultValue!=null?Yn(l,!!o.multiple,o.defaultValue,!0):Yn(l,!!o.multiple,o.multiple?[]:\"\",!1))}l[Wt]=o}catch(k){U(e,e.return,k)}}break;case 6:if(Ce(n,e),Oe(e),r&4){if(e.stateNode===null)throw Error(h(162));l=e.stateNode,o=e.memoizedProps;try{l.nodeValue=o}catch(k){U(e,e.return,k)}}break;case 3:if(Ce(n,e),Oe(e),r&4&&t!==null&&t.memoizedState.isDehydrated)try{Ut(n.containerInfo)}catch(k){U(e,e.return,k)}break;case 4:Ce(n,e),Oe(e);break;case 13:Ce(n,e),Oe(e),l=e.child,l.flags&8192&&(o=l.memoizedState!==null,l.stateNode.isHidden=o,!o||l.alternate!==null&&l.alternate.memoizedState!==null||(Uu=A())),r&4&&gs(e);break;case 22:if(m=t!==null&&t.memoizedState!==null,e.mode&1?(b=(f=b)||m,Ce(n,e),b=f):Ce(n,e),Oe(e),r&8192){if(f=e.memoizedState!==null,(e.stateNode.isHidden=f)&&!m&&e.mode&1)for(w=e,m=e.child;m!==null;){for(v=w=m;w!==null;){switch(p=w,g=p.child,p.tag){case 0:case 11:case 14:case 15:Lt(4,p,p.return);break;case 1:Qn(p,p.return);var S=p.stateNode;if(typeof S.componentWillUnmount==\"function\"){r=p,t=p.return;try{n=r,S.props=n.memoizedProps,S.state=n.memoizedState,S.componentWillUnmount()}catch(k){U(r,t,k)}}break;case 5:Qn(p,p.return);break;case 22:if(p.memoizedState!==null){Ss(v);continue}}g!==null?(g.return=p,w=g):Ss(v)}m=m.sibling}e:for(m=null,v=e;;){if(v.tag===5){if(m===null){m=v;try{l=v.stateNode,f?(o=l.style,typeof o.setProperty==\"function\"?o.setProperty(\"display\",\"none\",\"important\"):o.display=\"none\"):(i=v.stateNode,s=v.memoizedProps.style,u=s!=null&&s.hasOwnProperty(\"display\")?s.display:null,i.style.display=js(\"display\",u))}catch(k){U(e,e.return,k)}}}else if(v.tag===6){if(m===null)try{v.stateNode.nodeValue=f?\"\":v.memoizedProps}catch(k){U(e,e.return,k)}}else if((v.tag!==22&&v.tag!==23||v.memoizedState===null||v===e)&&v.child!==null){v.child.return=v,v=v.child;continue}if(v===e)break e;for(;v.sibling===null;){if(v.return===null||v.return===e)break e;m===v&&(m=null),v=v.return}m===v&&(m=null),v.sibling.return=v.return,v=v.sibling}}break;case 19:Ce(n,e),Oe(e),r&4&&gs(e);break;case 21:break;default:Ce(n,e),Oe(e)}}function Oe(e){var n=e.flags;if(n&2){try{e:{for(var t=e.return;t!==null;){if(cc(t)){var r=t;break e}t=t.return}throw Error(h(160))}switch(r.tag){case 5:var l=r.stateNode;r.flags&32&&(Mt(l,\"\"),r.flags&=-33);var o=ys(e);qo(e,o,l);break;case 3:case 4:var u=r.stateNode.containerInfo,i=ys(e);Jo(e,i,u);break;default:throw Error(h(161))}}catch(s){U(e,e.return,s)}e.flags&=-3}n&4096&&(e.flags&=-4097)}function Yd(e,n,t){w=e,pc(e,n,t)}function pc(e,n,t){for(var r=(e.mode&1)!==0;w!==null;){var l=w,o=l.child;if(l.tag===22&&r){var u=l.memoizedState!==null||Pr;if(!u){var i=l.alternate,s=i!==null&&i.memoizedState!==null||b;i=Pr;var f=b;if(Pr=u,(b=s)&&!f)for(w=l;w!==null;)u=w,s=u.child,u.tag===22&&u.memoizedState!==null?ks(l):s!==null?(s.return=u,w=s):ks(l);for(;o!==null;)w=o,pc(o,n,t),o=o.sibling;w=l,Pr=i,b=f}ws(e,n,t)}else l.subtreeFlags&8772&&o!==null?(o.return=l,w=o):ws(e,n,t)}}function ws(e){for(;w!==null;){var n=w;if(n.flags&8772){var t=n.alternate;try{if(n.flags&8772)switch(n.tag){case 0:case 11:case 15:b||yl(5,n);break;case 1:var r=n.stateNode;if(n.flags&4&&!b)if(t===null)r.componentDidMount();else{var l=n.elementType===n.type?t.memoizedProps:xe(n.type,t.memoizedProps);r.componentDidUpdate(l,t.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var o=n.updateQueue;o!==null&&ts(n,o,r);break;case 3:var u=n.updateQueue;if(u!==null){if(t=null,n.child!==null)switch(n.child.tag){case 5:t=n.child.stateNode;break;case 1:t=n.child.stateNode}ts(n,u,t)}break;case 5:var i=n.stateNode;if(t===null&&n.flags&4){t=i;var s=n.memoizedProps;switch(n.type){case\"button\":case\"input\":case\"select\":case\"textarea\":s.autoFocus&&t.focus();break;case\"img\":s.src&&(t.src=s.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(n.memoizedState===null){var f=n.alternate;if(f!==null){var m=f.memoizedState;if(m!==null){var v=m.dehydrated;v!==null&&Ut(v)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(h(163))}b||n.flags&512&&Zo(n)}catch(p){U(n,n.return,p)}}if(n===e){w=null;break}if(t=n.sibling,t!==null){t.return=n.return,w=t;break}w=n.return}}function Ss(e){for(;w!==null;){var n=w;if(n===e){w=null;break}var t=n.sibling;if(t!==null){t.return=n.return,w=t;break}w=n.return}}function ks(e){for(;w!==null;){var n=w;try{switch(n.tag){case 0:case 11:case 15:var t=n.return;try{yl(4,n)}catch(s){U(n,t,s)}break;case 1:var r=n.stateNode;if(typeof r.componentDidMount==\"function\"){var l=n.return;try{r.componentDidMount()}catch(s){U(n,l,s)}}var o=n.return;try{Zo(n)}catch(s){U(n,o,s)}break;case 5:var u=n.return;try{Zo(n)}catch(s){U(n,u,s)}}}catch(s){U(n,n.return,s)}if(n===e){w=null;break}var i=n.sibling;if(i!==null){i.return=n.return,w=i;break}w=n.return}}var Xd=Math.ceil,ll=Ye.ReactCurrentDispatcher,Fu=Ye.ReactCurrentOwner,Se=Ye.ReactCurrentBatchConfig,P=0,K=null,H=null,X=0,ce=0,Kn=vn(0),W=0,Gt=null,zn=0,gl=0,ju=0,Rt=null,oe=null,Uu=0,ot=1/0,Ue=null,ol=!1,bo=null,an=null,zr=!1,tn=null,ul=0,Ot=0,eu=null,Fr=-1,jr=0;function re(){return P&6?A():Fr!==-1?Fr:Fr=A()}function cn(e){return e.mode&1?P&2&&X!==0?X&-X:Rd.transition!==null?(jr===0&&(jr=Zs()),jr):(e=T,e!==0||(e=window.event,e=e===void 0?16:ra(e.type)),e):1}function Te(e,n,t,r){if(50<Ot)throw Ot=0,eu=null,Error(h(185));Zt(e,t,r),(!(P&2)||e!==K)&&(e===K&&(!(P&2)&&(gl|=t),W===4&&en(e,X)),ae(e,r),t===1&&P===0&&!(n.mode&1)&&(ot=A()+500,ml&&hn()))}function ae(e,n){var t=e.callbackNode;Df(e,n);var r=Wr(e,e===K?X:0);if(r===0)t!==null&&Ti(t),e.callbackNode=null,e.callbackPriority=0;else if(n=r&-r,e.callbackPriority!==n){if(t!=null&&Ti(t),n===1)e.tag===0?Ld(Es.bind(null,e)):Ea(Es.bind(null,e)),Nd(function(){!(P&6)&&hn()}),t=null;else{switch(Js(r)){case 1:t=cu;break;case 4:t=Xs;break;case 16:t=Br;break;case 536870912:t=Gs;break;default:t=Br}t=kc(t,mc.bind(null,e))}e.callbackPriority=n,e.callbackNode=t}}function mc(e,n){if(Fr=-1,jr=0,P&6)throw Error(h(327));var t=e.callbackNode;if(qn()&&e.callbackNode!==t)return null;var r=Wr(e,e===K?X:0);if(r===0)return null;if(r&30||r&e.expiredLanes||n)n=il(e,r);else{n=r;var l=P;P|=2;var o=hc();(K!==e||X!==n)&&(Ue=null,ot=A()+500,_n(e,n));do try{Jd();break}catch(i){vc(e,i)}while(!0);_u(),ll.current=o,P=l,H!==null?n=0:(K=null,X=0,n=W)}if(n!==0){if(n===2&&(l=Po(e),l!==0&&(r=l,n=nu(e,l))),n===1)throw t=Gt,_n(e,0),en(e,r),ae(e,A()),t;if(n===6)en(e,r);else{if(l=e.current.alternate,!(r&30)&&!Gd(l)&&(n=il(e,r),n===2&&(o=Po(e),o!==0&&(r=o,n=nu(e,o))),n===1))throw t=Gt,_n(e,0),en(e,r),ae(e,A()),t;switch(e.finishedWork=l,e.finishedLanes=r,n){case 0:case 1:throw Error(h(345));case 2:wn(e,oe,Ue);break;case 3:if(en(e,r),(r&130023424)===r&&(n=Uu+500-A(),10<n)){if(Wr(e,0)!==0)break;if(l=e.suspendedLanes,(l&r)!==r){re(),e.pingedLanes|=e.suspendedLanes&l;break}e.timeoutHandle=Io(wn.bind(null,e,oe,Ue),n);break}wn(e,oe,Ue);break;case 4:if(en(e,r),(r&4194240)===r)break;for(n=e.eventTimes,l=-1;0<r;){var u=31-ze(r);o=1<<u,u=n[u],u>l&&(l=u),r&=~o}if(r=l,r=A()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Xd(r/1960))-r,10<r){e.timeoutHandle=Io(wn.bind(null,e,oe,Ue),r);break}wn(e,oe,Ue);break;case 5:wn(e,oe,Ue);break;default:throw Error(h(329))}}}return ae(e,A()),e.callbackNode===t?mc.bind(null,e):null}function nu(e,n){var t=Rt;return e.current.memoizedState.isDehydrated&&(_n(e,n).flags|=256),e=il(e,n),e!==2&&(n=oe,oe=t,n!==null&&tu(n)),e}function tu(e){oe===null?oe=e:oe.push.apply(oe,e)}function Gd(e){for(var n=e;;){if(n.flags&16384){var t=n.updateQueue;if(t!==null&&(t=t.stores,t!==null))for(var r=0;r<t.length;r++){var l=t[r],o=l.getSnapshot;l=l.value;try{if(!Le(o(),l))return!1}catch{return!1}}}if(t=n.child,n.subtreeFlags&16384&&t!==null)t.return=n,n=t;else{if(n===e)break;for(;n.sibling===null;){if(n.return===null||n.return===e)return!0;n=n.return}n.sibling.return=n.return,n=n.sibling}}return!0}function en(e,n){for(n&=~ju,n&=~gl,e.suspendedLanes|=n,e.pingedLanes&=~n,e=e.expirationTimes;0<n;){var t=31-ze(n),r=1<<t;e[t]=-1,n&=~r}}function Es(e){if(P&6)throw Error(h(327));qn();var n=Wr(e,0);if(!(n&1))return ae(e,A()),null;var t=il(e,n);if(e.tag!==0&&t===2){var r=Po(e);r!==0&&(n=r,t=nu(e,r))}if(t===1)throw t=Gt,_n(e,0),en(e,n),ae(e,A()),t;if(t===6)throw Error(h(345));return e.finishedWork=e.current.alternate,e.finishedLanes=n,wn(e,oe,Ue),ae(e,A()),null}function Vu(e,n){var t=P;P|=1;try{return e(n)}finally{P=t,P===0&&(ot=A()+500,ml&&hn())}}function Tn(e){tn!==null&&tn.tag===0&&!(P&6)&&qn();var n=P;P|=1;var t=Se.transition,r=T;try{if(Se.transition=null,T=1,e)return e()}finally{T=r,Se.transition=t,P=n,!(P&6)&&hn()}}function Au(){ce=Kn.current,D(Kn)}function _n(e,n){e.finishedWork=null,e.finishedLanes=0;var t=e.timeoutHandle;if(t!==-1&&(e.timeoutHandle=-1,xd(t)),H!==null)for(t=H.return;t!==null;){var r=t;switch(Su(r),r.tag){case 1:r=r.type.childContextTypes,r!=null&&Xr();break;case 3:rt(),D(ie),D(ee),Tu();break;case 5:zu(r);break;case 4:rt();break;case 13:D(I);break;case 19:D(I);break;case 10:Cu(r.type._context);break;case 22:case 23:Au()}t=t.return}if(K=e,H=e=fn(e.current,null),X=ce=n,W=0,Gt=null,ju=gl=zn=0,oe=Rt=null,kn!==null){for(n=0;n<kn.length;n++)if(t=kn[n],r=t.interleaved,r!==null){t.interleaved=null;var l=r.next,o=t.pending;if(o!==null){var u=o.next;o.next=l,r.next=u}t.pending=r}kn=null}return e}function vc(e,n){do{var t=H;try{if(_u(),Dr.current=rl,tl){for(var r=F.memoizedState;r!==null;){var l=r.queue;l!==null&&(l.pending=null),r=r.next}tl=!1}if(Pn=0,Q=B=F=null,Tt=!1,Kt=0,Fu.current=null,t===null||t.return===null){W=1,Gt=n,H=null;break}e:{var o=e,u=t.return,i=t,s=n;if(n=X,i.flags|=32768,s!==null&&typeof s==\"object\"&&typeof s.then==\"function\"){var f=s,m=i,v=m.tag;if(!(m.mode&1)&&(v===0||v===11||v===15)){var p=m.alternate;p?(m.updateQueue=p.updateQueue,m.memoizedState=p.memoizedState,m.lanes=p.lanes):(m.updateQueue=null,m.memoizedState=null)}var g=as(u);if(g!==null){g.flags&=-257,cs(g,u,i,o,n),g.mode&1&&ss(o,f,n),n=g,s=f;var S=n.updateQueue;if(S===null){var k=new Set;k.add(s),n.updateQueue=k}else S.add(s);break e}else{if(!(n&1)){ss(o,f,n),Hu();break e}s=Error(h(426))}}else if(M&&i.mode&1){var V=as(u);if(V!==null){!(V.flags&65536)&&(V.flags|=256),cs(V,u,i,o,n),ku(lt(s,i));break e}}o=s=lt(s,i),W!==4&&(W=2),Rt===null?Rt=[o]:Rt.push(o),o=u;do{switch(o.tag){case 3:o.flags|=65536,n&=-n,o.lanes|=n;var c=qa(o,s,n);ns(o,c);break e;case 1:i=s;var a=o.type,d=o.stateNode;if(!(o.flags&128)&&(typeof a.getDerivedStateFromError==\"function\"||d!==null&&typeof d.componentDidCatch==\"function\"&&(an===null||!an.has(d)))){o.flags|=65536,n&=-n,o.lanes|=n;var y=ba(o,i,n);ns(o,y);break e}}o=o.return}while(o!==null)}gc(t)}catch(E){n=E,H===t&&t!==null&&(H=t=t.return);continue}break}while(!0)}function hc(){var e=ll.current;return ll.current=rl,e===null?rl:e}function Hu(){(W===0||W===3||W===2)&&(W=4),K===null||!(zn&268435455)&&!(gl&268435455)||en(K,X)}function il(e,n){var t=P;P|=2;var r=hc();(K!==e||X!==n)&&(Ue=null,_n(e,n));do try{Zd();break}catch(l){vc(e,l)}while(!0);if(_u(),P=t,ll.current=r,H!==null)throw Error(h(261));return K=null,X=0,W}function Zd(){for(;H!==null;)yc(H)}function Jd(){for(;H!==null&&!Cf();)yc(H)}function yc(e){var n=Sc(e.alternate,e,ce);e.memoizedProps=e.pendingProps,n===null?gc(e):H=n,Fu.current=null}function gc(e){var n=e;do{var t=n.alternate;if(e=n.return,n.flags&32768){if(t=$d(t,n),t!==null){t.flags&=32767,H=t;return}if(e!==null)e.flags|=32768,e.subtreeFlags=0,e.deletions=null;else{W=6,H=null;return}}else if(t=Wd(t,n,ce),t!==null){H=t;return}if(n=n.sibling,n!==null){H=n;return}H=n=e}while(n!==null);W===0&&(W=5)}function wn(e,n,t){var r=T,l=Se.transition;try{Se.transition=null,T=1,qd(e,n,t,r)}finally{Se.transition=l,T=r}return null}function qd(e,n,t,r){do qn();while(tn!==null);if(P&6)throw Error(h(327));t=e.finishedWork;var l=e.finishedLanes;if(t===null)return null;if(e.finishedWork=null,e.finishedLanes=0,t===e.current)throw Error(h(177));e.callbackNode=null,e.callbackPriority=0;var o=t.lanes|t.childLanes;if(Mf(e,o),e===K&&(H=K=null,X=0),!(t.subtreeFlags&2064)&&!(t.flags&2064)||zr||(zr=!0,kc(Br,function(){return qn(),null})),o=(t.flags&15990)!==0,t.subtreeFlags&15990||o){o=Se.transition,Se.transition=null;var u=T;T=1;var i=P;P|=4,Fu.current=null,Kd(e,t),dc(t,e),Sd(Do),$r=!!Oo,Do=Oo=null,e.current=t,Yd(t,e,l),xf(),P=i,T=u,Se.transition=o}else e.current=t;if(zr&&(zr=!1,tn=e,ul=l),o=e.pendingLanes,o===0&&(an=null),zf(t.stateNode,r),ae(e,A()),n!==null)for(r=e.onRecoverableError,t=0;t<n.length;t++)l=n[t],r(l.value,{componentStack:l.stack,digest:l.digest});if(ol)throw ol=!1,e=bo,bo=null,e;return ul&1&&e.tag!==0&&qn(),o=e.pendingLanes,o&1?e===eu?Ot++:(Ot=0,eu=e):Ot=0,hn(),null}function qn(){if(tn!==null){var e=Js(ul),n=Se.transition,t=T;try{if(Se.transition=null,T=16>e?16:e,tn===null)var r=!1;else{if(e=tn,tn=null,ul=0,P&6)throw Error(h(331));var l=P;for(P|=4,w=e.current;w!==null;){var o=w,u=o.child;if(w.flags&16){var i=o.deletions;if(i!==null){for(var s=0;s<i.length;s++){var f=i[s];for(w=f;w!==null;){var m=w;switch(m.tag){case 0:case 11:case 15:Lt(8,m,o)}var v=m.child;if(v!==null)v.return=m,w=v;else for(;w!==null;){m=w;var p=m.sibling,g=m.return;if(ac(m),m===f){w=null;break}if(p!==null){p.return=g,w=p;break}w=g}}}var S=o.alternate;if(S!==null){var k=S.child;if(k!==null){S.child=null;do{var V=k.sibling;k.sibling=null,k=V}while(k!==null)}}w=o}}if(o.subtreeFlags&2064&&u!==null)u.return=o,w=u;else e:for(;w!==null;){if(o=w,o.flags&2048)switch(o.tag){case 0:case 11:case 15:Lt(9,o,o.return)}var c=o.sibling;if(c!==null){c.return=o.return,w=c;break e}w=o.return}}var a=e.current;for(w=a;w!==null;){u=w;var d=u.child;if(u.subtreeFlags&2064&&d!==null)d.return=u,w=d;else e:for(u=a;w!==null;){if(i=w,i.flags&2048)try{switch(i.tag){case 0:case 11:case 15:yl(9,i)}}catch(E){U(i,i.return,E)}if(i===u){w=null;break e}var y=i.sibling;if(y!==null){y.return=i.return,w=y;break e}w=i.return}}if(P=l,hn(),Ie&&typeof Ie.onPostCommitFiberRoot==\"function\")try{Ie.onPostCommitFiberRoot(al,e)}catch{}r=!0}return r}finally{T=t,Se.transition=n}}return!1}function _s(e,n,t){n=lt(t,n),n=qa(e,n,1),e=sn(e,n,1),n=re(),e!==null&&(Zt(e,1,n),ae(e,n))}function U(e,n,t){if(e.tag===3)_s(e,e,t);else for(;n!==null;){if(n.tag===3){_s(n,e,t);break}else if(n.tag===1){var r=n.stateNode;if(typeof n.type.getDerivedStateFromError==\"function\"||typeof r.componentDidCatch==\"function\"&&(an===null||!an.has(r))){e=lt(t,e),e=ba(n,e,1),n=sn(n,e,1),e=re(),n!==null&&(Zt(n,1,e),ae(n,e));break}}n=n.return}}function bd(e,n,t){var r=e.pingCache;r!==null&&r.delete(n),n=re(),e.pingedLanes|=e.suspendedLanes&t,K===e&&(X&t)===t&&(W===4||W===3&&(X&130023424)===X&&500>A()-Uu?_n(e,0):ju|=t),ae(e,n)}function wc(e,n){n===0&&(e.mode&1?(n=mr,mr<<=1,!(mr&130023424)&&(mr=4194304)):n=1);var t=re();e=Qe(e,n),e!==null&&(Zt(e,n,t),ae(e,t))}function ep(e){var n=e.memoizedState,t=0;n!==null&&(t=n.retryLane),wc(e,t)}function np(e,n){var t=0;switch(e.tag){case 13:var r=e.stateNode,l=e.memoizedState;l!==null&&(t=l.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(h(314))}r!==null&&r.delete(n),wc(e,t)}var Sc;Sc=function(e,n,t){if(e!==null)if(e.memoizedProps!==n.pendingProps||ie.current)ue=!0;else{if(!(e.lanes&t)&&!(n.flags&128))return ue=!1,Bd(e,n,t);ue=!!(e.flags&131072)}else ue=!1,M&&n.flags&1048576&&_a(n,Jr,n.index);switch(n.lanes=0,n.tag){case 2:var r=n.type;Ir(e,n),e=n.pendingProps;var l=et(n,ee.current);Jn(n,t),l=Ru(null,n,r,e,l,t);var o=Ou();return n.flags|=1,typeof l==\"object\"&&l!==null&&typeof l.render==\"function\"&&l.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,se(r)?(o=!0,Gr(n)):o=!1,n.memoizedState=l.state!==null&&l.state!==void 0?l.state:null,Nu(n),l.updater=vl,n.stateNode=l,l._reactInternals=n,Bo(n,r,e,t),n=Qo(null,n,r,!0,o,t)):(n.tag=0,M&&o&&wu(n),te(null,n,l,t),n=n.child),n;case 16:r=n.elementType;e:{switch(Ir(e,n),e=n.pendingProps,l=r._init,r=l(r._payload),n.type=r,l=n.tag=rp(r),e=xe(r,e),l){case 0:n=$o(null,n,r,e,t);break e;case 1:n=ps(null,n,r,e,t);break e;case 11:n=fs(null,n,r,e,t);break e;case 14:n=ds(null,n,r,xe(r.type,e),t);break e}throw Error(h(306,r,\"\"))}return n;case 0:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:xe(r,l),$o(e,n,r,l,t);case 1:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:xe(r,l),ps(e,n,r,l,t);case 3:e:{if(rc(n),e===null)throw Error(h(387));r=n.pendingProps,o=n.memoizedState,l=o.element,Pa(e,n),el(n,r,null,t);var u=n.memoizedState;if(r=u.element,o.isDehydrated)if(o={element:r,isDehydrated:!1,cache:u.cache,pendingSuspenseBoundaries:u.pendingSuspenseBoundaries,transitions:u.transitions},n.updateQueue.baseState=o,n.memoizedState=o,n.flags&256){l=lt(Error(h(423)),n),n=ms(e,n,r,t,l);break e}else if(r!==l){l=lt(Error(h(424)),n),n=ms(e,n,r,t,l);break e}else for(fe=un(n.stateNode.containerInfo.firstChild),de=n,M=!0,Pe=null,t=Ra(n,null,r,t),n.child=t;t;)t.flags=t.flags&-3|4096,t=t.sibling;else{if(nt(),r===l){n=Ke(e,n,t);break e}te(e,n,r,t)}n=n.child}return n;case 5:return Oa(n),e===null&&Vo(n),r=n.type,l=n.pendingProps,o=e!==null?e.memoizedProps:null,u=l.children,Mo(r,l)?u=null:o!==null&&Mo(r,o)&&(n.flags|=32),tc(e,n),te(e,n,u,t),n.child;case 6:return e===null&&Vo(n),null;case 13:return lc(e,n,t);case 4:return Pu(n,n.stateNode.containerInfo),r=n.pendingProps,e===null?n.child=tt(n,null,r,t):te(e,n,r,t),n.child;case 11:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:xe(r,l),fs(e,n,r,l,t);case 7:return te(e,n,n.pendingProps,t),n.child;case 8:return te(e,n,n.pendingProps.children,t),n.child;case 12:return te(e,n,n.pendingProps.children,t),n.child;case 10:e:{if(r=n.type._context,l=n.pendingProps,o=n.memoizedProps,u=l.value,R(qr,r._currentValue),r._currentValue=u,o!==null)if(Le(o.value,u)){if(o.children===l.children&&!ie.current){n=Ke(e,n,t);break e}}else for(o=n.child,o!==null&&(o.return=n);o!==null;){var i=o.dependencies;if(i!==null){u=o.child;for(var s=i.firstContext;s!==null;){if(s.context===r){if(o.tag===1){s=Be(-1,t&-t),s.tag=2;var f=o.updateQueue;if(f!==null){f=f.shared;var m=f.pending;m===null?s.next=s:(s.next=m.next,m.next=s),f.pending=s}}o.lanes|=t,s=o.alternate,s!==null&&(s.lanes|=t),Ao(o.return,t,n),i.lanes|=t;break}s=s.next}}else if(o.tag===10)u=o.type===n.type?null:o.child;else if(o.tag===18){if(u=o.return,u===null)throw Error(h(341));u.lanes|=t,i=u.alternate,i!==null&&(i.lanes|=t),Ao(u,t,n),u=o.sibling}else u=o.child;if(u!==null)u.return=o;else for(u=o;u!==null;){if(u===n){u=null;break}if(o=u.sibling,o!==null){o.return=u.return,u=o;break}u=u.return}o=u}te(e,n,l.children,t),n=n.child}return n;case 9:return l=n.type,r=n.pendingProps.children,Jn(n,t),l=ke(l),r=r(l),n.flags|=1,te(e,n,r,t),n.child;case 14:return r=n.type,l=xe(r,n.pendingProps),l=xe(r.type,l),ds(e,n,r,l,t);case 15:return ec(e,n,n.type,n.pendingProps,t);case 17:return r=n.type,l=n.pendingProps,l=n.elementType===r?l:xe(r,l),Ir(e,n),n.tag=1,se(r)?(e=!0,Gr(n)):e=!1,Jn(n,t),Ta(n,r,l),Bo(n,r,l,t),Qo(null,n,r,!0,e,t);case 19:return oc(e,n,t);case 22:return nc(e,n,t)}throw Error(h(156,n.tag))};function kc(e,n){return Ys(e,n)}function tp(e,n,t,r){this.tag=e,this.key=t,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function we(e,n,t,r){return new tp(e,n,t,r)}function Bu(e){return e=e.prototype,!(!e||!e.isReactComponent)}function rp(e){if(typeof e==\"function\")return Bu(e)?1:0;if(e!=null){if(e=e.$$typeof,e===iu)return 11;if(e===su)return 14}return 2}function fn(e,n){var t=e.alternate;return t===null?(t=we(e.tag,n,e.key,e.mode),t.elementType=e.elementType,t.type=e.type,t.stateNode=e.stateNode,t.alternate=e,e.alternate=t):(t.pendingProps=n,t.type=e.type,t.flags=0,t.subtreeFlags=0,t.deletions=null),t.flags=e.flags&14680064,t.childLanes=e.childLanes,t.lanes=e.lanes,t.child=e.child,t.memoizedProps=e.memoizedProps,t.memoizedState=e.memoizedState,t.updateQueue=e.updateQueue,n=e.dependencies,t.dependencies=n===null?null:{lanes:n.lanes,firstContext:n.firstContext},t.sibling=e.sibling,t.index=e.index,t.ref=e.ref,t}function Ur(e,n,t,r,l,o){var u=2;if(r=e,typeof e==\"function\")Bu(e)&&(u=1);else if(typeof e==\"string\")u=5;else e:switch(e){case Fn:return Cn(t.children,l,o,n);case uu:u=8,l|=8;break;case fo:return e=we(12,t,n,l|2),e.elementType=fo,e.lanes=o,e;case po:return e=we(13,t,n,l),e.elementType=po,e.lanes=o,e;case mo:return e=we(19,t,n,l),e.elementType=mo,e.lanes=o,e;case Ls:return wl(t,l,o,n);default:if(typeof e==\"object\"&&e!==null)switch(e.$$typeof){case zs:u=10;break e;case Ts:u=9;break e;case iu:u=11;break e;case su:u=14;break e;case Je:u=16,r=null;break e}throw Error(h(130,e==null?e:typeof e,\"\"))}return n=we(u,t,n,l),n.elementType=e,n.type=r,n.lanes=o,n}function Cn(e,n,t,r){return e=we(7,e,r,n),e.lanes=t,e}function wl(e,n,t,r){return e=we(22,e,r,n),e.elementType=Ls,e.lanes=t,e.stateNode={isHidden:!1},e}function so(e,n,t){return e=we(6,e,null,n),e.lanes=t,e}function ao(e,n,t){return n=we(4,e.children!==null?e.children:[],e.key,n),n.lanes=t,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function lp(e,n,t,r,l){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Kl(0),this.expirationTimes=Kl(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Kl(0),this.identifierPrefix=r,this.onRecoverableError=l,this.mutableSourceEagerHydrationData=null}function Wu(e,n,t,r,l,o,u,i,s){return e=new lp(e,n,t,i,s),n===1?(n=1,o===!0&&(n|=8)):n=0,o=we(3,null,null,n),e.current=o,o.stateNode=e,o.memoizedState={element:r,isDehydrated:t,cache:null,transitions:null,pendingSuspenseBoundaries:null},Nu(o),e}function op(e,n,t){var r=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:In,key:r==null?null:\"\"+r,children:e,containerInfo:n,implementation:t}}function Ec(e){if(!e)return pn;e=e._reactInternals;e:{if(Rn(e)!==e||e.tag!==1)throw Error(h(170));var n=e;do{switch(n.tag){case 3:n=n.stateNode.context;break e;case 1:if(se(n.type)){n=n.stateNode.__reactInternalMemoizedMergedChildContext;break e}}n=n.return}while(n!==null);throw Error(h(171))}if(e.tag===1){var t=e.type;if(se(t))return ka(e,t,n)}return n}function _c(e,n,t,r,l,o,u,i,s){return e=Wu(t,r,!0,e,l,o,u,i,s),e.context=Ec(null),t=e.current,r=re(),l=cn(t),o=Be(r,l),o.callback=n??null,sn(t,o,l),e.current.lanes=l,Zt(e,l,r),ae(e,r),e}function Sl(e,n,t,r){var l=n.current,o=re(),u=cn(l);return t=Ec(t),n.context===null?n.context=t:n.pendingContext=t,n=Be(o,u),n.payload={element:e},r=r===void 0?null:r,r!==null&&(n.callback=r),e=sn(l,n,u),e!==null&&(Te(e,l,u,o),Or(e,l,u)),u}function sl(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return e.child.stateNode;default:return e.child.stateNode}}function Cs(e,n){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var t=e.retryLane;e.retryLane=t!==0&&t<n?t:n}}function $u(e,n){Cs(e,n),(e=e.alternate)&&Cs(e,n)}function up(){return null}var Cc=typeof reportError==\"function\"?reportError:function(e){console.error(e)};function Qu(e){this._internalRoot=e}kl.prototype.render=Qu.prototype.render=function(e){var n=this._internalRoot;if(n===null)throw Error(h(409));Sl(e,n,null,null)};kl.prototype.unmount=Qu.prototype.unmount=function(){var e=this._internalRoot;if(e!==null){this._internalRoot=null;var n=e.containerInfo;Tn(function(){Sl(null,e,null,null)}),n[$e]=null}};function kl(e){this._internalRoot=e}kl.prototype.unstable_scheduleHydration=function(e){if(e){var n=ea();e={blockedOn:null,target:e,priority:n};for(var t=0;t<be.length&&n!==0&&n<be[t].priority;t++);be.splice(t,0,e),t===0&&ta(e)}};function Ku(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function El(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11&&(e.nodeType!==8||e.nodeValue!==\" react-mount-point-unstable \"))}function xs(){}function ip(e,n,t,r,l){if(l){if(typeof r==\"function\"){var o=r;r=function(){var f=sl(u);o.call(f)}}var u=_c(n,r,e,0,null,!1,!1,\"\",xs);return e._reactRootContainer=u,e[$e]=u.current,Ht(e.nodeType===8?e.parentNode:e),Tn(),u}for(;l=e.lastChild;)e.removeChild(l);if(typeof r==\"function\"){var i=r;r=function(){var f=sl(s);i.call(f)}}var s=Wu(e,0,!1,null,null,!1,!1,\"\",xs);return e._reactRootContainer=s,e[$e]=s.current,Ht(e.nodeType===8?e.parentNode:e),Tn(function(){Sl(n,s,t,r)}),s}function _l(e,n,t,r,l){var o=t._reactRootContainer;if(o){var u=o;if(typeof l==\"function\"){var i=l;l=function(){var s=sl(u);i.call(s)}}Sl(n,u,e,l)}else u=ip(t,n,e,l,r);return sl(u)}qs=function(e){switch(e.tag){case 3:var n=e.stateNode;if(n.current.memoizedState.isDehydrated){var t=Et(n.pendingLanes);t!==0&&(fu(n,t|1),ae(n,A()),!(P&6)&&(ot=A()+500,hn()))}break;case 13:Tn(function(){var r=Qe(e,1);if(r!==null){var l=re();Te(r,e,1,l)}}),$u(e,1)}};du=function(e){if(e.tag===13){var n=Qe(e,134217728);if(n!==null){var t=re();Te(n,e,134217728,t)}$u(e,134217728)}};bs=function(e){if(e.tag===13){var n=cn(e),t=Qe(e,n);if(t!==null){var r=re();Te(t,e,n,r)}$u(e,n)}};ea=function(){return T};na=function(e,n){var t=T;try{return T=e,n()}finally{T=t}};Co=function(e,n,t){switch(n){case\"input\":if(yo(e,t),n=t.name,t.type===\"radio\"&&n!=null){for(t=e;t.parentNode;)t=t.parentNode;for(t=t.querySelectorAll(\"input[name=\"+JSON.stringify(\"\"+n)+'][type=\"radio\"]'),n=0;n<t.length;n++){var r=t[n];if(r!==e&&r.form===e.form){var l=pl(r);if(!l)throw Error(h(90));Os(r),yo(r,l)}}}break;case\"textarea\":Ms(e,t);break;case\"select\":n=t.value,n!=null&&Yn(e,!!t.multiple,n,!1)}};Hs=Vu;Bs=Tn;var sp={usingClientEntryPoint:!1,Events:[qt,An,pl,Vs,As,Vu]},gt={findFiberByHostInstance:Sn,bundleType:0,version:\"18.2.0\",rendererPackageName:\"react-dom\"},ap={bundleType:gt.bundleType,version:gt.version,rendererPackageName:gt.rendererPackageName,rendererConfig:gt.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Ye.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return e=Qs(e),e===null?null:e.stateNode},findFiberByHostInstance:gt.findFiberByHostInstance||up,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:\"18.2.0-next-9e3b772b8-20220608\"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<\"u\"&&(wt=__REACT_DEVTOOLS_GLOBAL_HOOK__,!wt.isDisabled&&wt.supportsFiber))try{al=wt.inject(ap),Ie=wt}catch{}var wt;ve.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=sp;ve.createPortal=function(e,n){var t=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!Ku(n))throw Error(h(200));return op(e,n,null,t)};ve.createRoot=function(e,n){if(!Ku(e))throw Error(h(299));var t=!1,r=\"\",l=Cc;return n!=null&&(n.unstable_strictMode===!0&&(t=!0),n.identifierPrefix!==void 0&&(r=n.identifierPrefix),n.onRecoverableError!==void 0&&(l=n.onRecoverableError)),n=Wu(e,1,!1,null,null,t,!1,r,l),e[$e]=n.current,Ht(e.nodeType===8?e.parentNode:e),new Qu(n)};ve.findDOMNode=function(e){if(e==null)return null;if(e.nodeType===1)return e;var n=e._reactInternals;if(n===void 0)throw typeof e.render==\"function\"?Error(h(188)):(e=Object.keys(e).join(\",\"),Error(h(268,e)));return e=Qs(n),e=e===null?null:e.stateNode,e};ve.flushSync=function(e){return Tn(e)};ve.hydrate=function(e,n,t){if(!El(n))throw Error(h(200));return _l(null,e,n,!0,t)};ve.hydrateRoot=function(e,n,t){if(!Ku(e))throw Error(h(405));var r=t!=null&&t.hydratedSources||null,l=!1,o=\"\",u=Cc;if(t!=null&&(t.unstable_strictMode===!0&&(l=!0),t.identifierPrefix!==void 0&&(o=t.identifierPrefix),t.onRecoverableError!==void 0&&(u=t.onRecoverableError)),n=_c(n,null,e,1,t??null,l,!1,o,u),e[$e]=n.current,Ht(e),r)for(e=0;e<r.length;e++)t=r[e],l=t._getVersion,l=l(t._source),n.mutableSourceEagerHydrationData==null?n.mutableSourceEagerHydrationData=[t,l]:n.mutableSourceEagerHydrationData.push(t,l);return new kl(n)};ve.render=function(e,n,t){if(!El(n))throw Error(h(200));return _l(null,e,n,!1,t)};ve.unmountComponentAtNode=function(e){if(!El(e))throw Error(h(40));return e._reactRootContainer?(Tn(function(){_l(null,null,e,!1,function(){e._reactRootContainer=null,e[$e]=null})}),!0):!1};ve.unstable_batchedUpdates=Vu;ve.unstable_renderSubtreeIntoContainer=function(e,n,t,r){if(!El(t))throw Error(h(200));if(e==null||e._reactInternals===void 0)throw Error(h(38));return _l(e,n,t,!1,r)};ve.version=\"18.2.0-next-9e3b772b8-20220608\"});var zc=je((Np,Pc)=>{\"use strict\";function Nc(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>\"u\"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=\"function\"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(Nc)}catch(e){console.error(e)}}Nc(),Pc.exports=xc()});var Lc=je(Yu=>{\"use strict\";var Tc=zc();Yu.createRoot=Tc.createRoot,Yu.hydrateRoot=Tc.hydrateRoot;var Pp});var Oc=je(Cl=>{\"use strict\";var cp=Ol(),fp=Symbol.for(\"react.element\"),dp=Symbol.for(\"react.fragment\"),pp=Object.prototype.hasOwnProperty,mp=cp.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,vp={key:!0,ref:!0,__self:!0,__source:!0};function Rc(e,n,t){var r,l={},o=null,u=null;t!==void 0&&(o=\"\"+t),n.key!==void 0&&(o=\"\"+n.key),n.ref!==void 0&&(u=n.ref);for(r in n)pp.call(n,r)&&!vp.hasOwnProperty(r)&&(l[r]=n[r]);if(e&&e.defaultProps)for(r in n=e.defaultProps,n)l[r]===void 0&&(l[r]=n[r]);return{$$typeof:fp,type:e,key:o,ref:u,props:l,_owner:mp.current}}Cl.Fragment=dp;Cl.jsx=Rc;Cl.jsxs=Rc});var Xu=je((Lp,Dc)=>{\"use strict\";Dc.exports=Oc()});var wp={};Qc(wp,{renderHello:()=>gp});var xl=Nl(Lc());var er=Nl(Xu()),Mc=()=>(0,er.jsx)(\"h1\",{children:\"React component Header\"}),Ic=()=>(0,er.jsx)(\"div\",{children:\"This is client-side content from React\"}),Fc=e=>(0,er.jsxs)(\"div\",{children:[\"Hello \",e,\" (Client-side React, rendering server-side data)\"]});var jc=document.getElementById(\"react-header\");if(!jc)throw new Error(\"Could not find element with id react-header\");var hp=(0,xl.createRoot)(jc);hp.render(Mc());var Uc=document.getElementById(\"react-content\");if(!Uc)throw new Error(\"Could not find element with id react-content\");var yp=(0,xl.createRoot)(Uc);yp.render(Ic());function gp(e){let n=e.getAttribute(\"data-name\")??\"\";(0,xl.createRoot)(e).render(Fc(n))}return Kc(wp);})();\n/*! Bundled license information:\n\nreact/cjs/react.production.min.js:\n  (**\n   * @license React\n   * react.production.min.js\n   *\n   * Copyright (c) Facebook, Inc. and its affiliates.\n   *\n   * This source code is licensed under the MIT license found in the\n   * LICENSE file in the root directory of this source tree.\n   *)\n\nscheduler/cjs/scheduler.production.min.js:\n  (**\n   * @license React\n   * scheduler.production.min.js\n   *\n   * Copyright (c) Facebook, Inc. and its affiliates.\n   *\n   * This source code is licensed under the MIT license found in the\n   * LICENSE file in the root directory of this source tree.\n   *)\n\nreact-dom/cjs/react-dom.production.min.js:\n  (**\n   * @license React\n   * react-dom.production.min.js\n   *\n   * Copyright (c) Facebook, Inc. and its affiliates.\n   *\n   * This source code is licensed under the MIT license found in the\n   * LICENSE file in the root directory of this source tree.\n   *)\n\nreact/cjs/react-jsx-runtime.production.min.js:\n  (**\n   * @license React\n   * react-jsx-runtime.production.min.js\n   *\n   * Copyright (c) Facebook, Inc. and its affiliates.\n   *\n   * This source code is licensed under the MIT license found in the\n   * LICENSE file in the root directory of this source tree.\n   *)\n*/\n"
  },
  {
    "path": "examples/internationalization/components.templ",
    "content": "package main\n\nimport \"github.com/invopop/ctxi18n/i18n\"\n\ntempl page() {\n\t<html>\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<title>{ i18n.T(ctx, \"hello\") }</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>{ i18n.T(ctx, \"hello\") }</h1>\n\t\t\t<h2>{ i18n.T(ctx, \"select_language\") }</h2>\n\t\t\t<ul>\n\t\t\t\t<li><a href=\"/en\">English</a></li>\n\t\t\t\t<li><a href=\"/de\">Deutsch</a></li>\n\t\t\t\t<li><a href=\"/zh-cn\">中文</a></li>\n\t\t\t</ul>\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/internationalization/components_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"github.com/invopop/ctxi18n/i18n\"\n\nfunc page() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<html><head><meta charset=\\\"UTF-8\\\"><meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"><title>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.T(ctx, \"hello\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/internationalization/components.templ`, Line: 10, Col: 32}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</title></head><body><h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.T(ctx, \"hello\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/internationalization/components.templ`, Line: 13, Col: 29}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</h1><h2>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.T(ctx, \"select_language\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/internationalization/components.templ`, Line: 14, Col: 39}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</h2><ul><li><a href=\\\"/en\\\">English</a></li><li><a href=\\\"/de\\\">Deutsch</a></li><li><a href=\\\"/zh-cn\\\">中文</a></li></ul></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/internationalization/go.mod",
    "content": "module github.com/a-h/templ/examples/internationalization\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.731\n\tgithub.com/invopop/ctxi18n v0.8.1\n)\n\nrequire (\n\tgithub.com/invopop/yaml v0.3.1 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/internationalization/go.sum",
    "content": "github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/invopop/ctxi18n v0.8.1 h1:nfy5Mk6UfvLbGRBwpTi4T1g95+rmRo8bMllUmpCvVwI=\ngithub.com/invopop/ctxi18n v0.8.1/go.mod h1:1Osw+JGYA+anHt0Z4reF36r5FtGHYjGQ+m1X7keIhPc=\ngithub.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=\ngithub.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "examples/internationalization/locales/de/de.yaml",
    "content": "de:\n  hello: Hallo\n  select_language: Sprache auswählen\n"
  },
  {
    "path": "examples/internationalization/locales/en/en.yaml",
    "content": "en:\n  hello: \"Hello\"\n  select_language: \"Select Language\"\n"
  },
  {
    "path": "examples/internationalization/locales/locales.go",
    "content": "package locales\n\nimport \"embed\"\n\n//go:embed en\n//go:embed de\n//go:embed zh-cn\n\nvar Content embed.FS\n"
  },
  {
    "path": "examples/internationalization/locales/zh-cn/zh-cn.yaml",
    "content": "zh-cn:\n  hello: \"你好\"\n  select_language: \"选择语言\"\n"
  },
  {
    "path": "examples/internationalization/main.go",
    "content": "package main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/examples/internationalization/locales\"\n\t\"github.com/invopop/ctxi18n\"\n)\n\nfunc newLanguageMiddleware(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tlang := \"en\" // Default language\n\t\tpathSegments := strings.Split(r.URL.Path, \"/\")\n\t\tif len(pathSegments) > 1 {\n\t\t\tlang = pathSegments[1]\n\t\t}\n\t\tctx, err := ctxi18n.WithLocale(r.Context(), lang)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"error setting locale: %v\", err)\n\t\t\thttp.Error(w, \"error setting locale\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\tnext.ServeHTTP(w, r.WithContext(ctx))\n\t})\n}\n\nfunc main() {\n\tif err := ctxi18n.Load(locales.Content); err != nil {\n\t\tlog.Fatalf(\"error loading locales: %v\", err)\n\t}\n\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/\", templ.Handler(page()))\n\n\twithLanguageMiddleware := newLanguageMiddleware(mux)\n\n\tlog.Println(\"listening on :8080\")\n\tif err := http.ListenAndServe(\"127.0.0.1:8080\", withLanguageMiddleware); err != nil {\n\t\tlog.Printf(\"error listening: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "examples/static-generator/.gitignore",
    "content": "public\n"
  },
  {
    "path": "examples/static-generator/Dockerfile",
    "content": "FROM pierrezemb/gostatic\nCOPY ./public/ /srv/http/\nENTRYPOINT [\"/goStatic\", \"-port\", \"8080\"]\n"
  },
  {
    "path": "examples/static-generator/blog.templ",
    "content": "package main\n\nimport (\n\t\"github.com/gosimple/slug\"\n\t\"path\"\n)\n\ntempl headerComponent(title string) {\n\t<head><title>{ title }</title></head>\n}\n\ntempl contentComponent(title string, body templ.Component) {\n\t<body>\n\t\t<h1>{ title }</h1>\n\t\t<div class=\"content\">\n\t\t\t@body\n\t\t</div>\n\t</body>\n}\n\ntempl contentPage(title string, body templ.Component) {\n\t<html>\n\t\t@headerComponent(title)\n\t\t@contentComponent(title, body)\n\t</html>\n}\n\ntempl indexPage(posts []Post) {\n\t<html>\n\t\t@headerComponent(\"My Blog\")\n\t\t<body>\n\t\t\t<h1>My Blog</h1>\n\t\t\tfor _, post := range posts {\n\t\t\t\t<div><a href={ templ.SafeURL(path.Join(post.Date.Format(\"2006/01/02\"), slug.Make(post.Title), \"/\")) }>{ post.Title }</a></div>\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/static-generator/blog_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport (\n\t\"github.com/gosimple/slug\"\n\t\"path\"\n)\n\nfunc headerComponent(title string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<head><title>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/static-generator/blog.templ`, Line: 9, Col: 21}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</title></head>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc contentComponent(title string, body templ.Component) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<body><h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(title)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/static-generator/blog.templ`, Line: 14, Col: 13}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</h1><div class=\\\"content\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = body.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</div></body>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc contentPage(title string, body templ.Component) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = headerComponent(title).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = contentComponent(title, body).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"</html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc indexPage(posts []Post) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var6 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var6 == nil {\n\t\t\ttempl_7745c5c3_Var6 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = headerComponent(\"My Blog\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"<body><h1>My Blog</h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor _, post := range posts {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"<div><a href=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var7 templ.SafeURL\n\t\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(path.Join(post.Date.Format(\"2006/01/02\"), slug.Make(post.Title), \"/\")))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/static-generator/blog.templ`, Line: 34, Col: 103}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"\\\">\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var8 string\n\t\t\ttempl_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(post.Title)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/static-generator/blog.templ`, Line: 34, Col: 118}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"</a></div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/static-generator/fly.toml",
    "content": "# fly.toml file generated for cold-water-2865 on 2023-04-27T10:52:30+01:00\n\napp = \"cold-water-2865\"\nkill_signal = \"SIGINT\"\nkill_timeout = 5\nprimary_region = \"lhr\"\nprocesses = []\n\n[build]\n\n[env]\n\n[experimental]\n  auto_rollback = true\n\n[[services]]\n  http_checks = []\n  internal_port = 8080\n  processes = [\"app\"]\n  protocol = \"tcp\"\n  script_checks = []\n  [services.concurrency]\n    hard_limit = 25\n    soft_limit = 20\n    type = \"connections\"\n\n  [[services.ports]]\n    force_https = true\n    handlers = [\"http\"]\n    port = 80\n\n  [[services.ports]]\n    handlers = [\"tls\", \"http\"]\n    port = 443\n\n  [[services.tcp_checks]]\n    grace_period = \"1s\"\n    interval = \"15s\"\n    restart_limit = 0\n    timeout = \"2s\"\n"
  },
  {
    "path": "examples/static-generator/go.mod",
    "content": "module github.com/a-h/templ/examples/static-generator\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/templ v0.2.233\n\tgithub.com/gosimple/slug v1.14.0\n)\n\nrequire (\n\tgithub.com/gosimple/unidecode v1.0.1 // indirect\n\tgithub.com/yuin/goldmark v1.7.4\n)\n\nreplace github.com/a-h/templ => ../../\n"
  },
  {
    "path": "examples/static-generator/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es=\ngithub.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=\ngithub.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o=\ngithub.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=\ngithub.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=\ngithub.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=\n"
  },
  {
    "path": "examples/static-generator/main.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"time\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/gosimple/slug\"\n\t\"github.com/yuin/goldmark\"\n)\n\ntype Post struct {\n\tDate    time.Time\n\tTitle   string\n\tContent string\n}\n\nfunc Unsafe(html string) templ.Component {\n\treturn templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\t_, err = io.WriteString(w, html)\n\t\treturn\n\t})\n}\n\nfunc main() {\n\tposts := []Post{\n\t\t{\n\t\t\tDate:  time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC),\n\t\t\tTitle: \"Happy New Year!\",\n\t\t\tContent: `New Year is a widely celebrated occasion in the United Kingdom, marking the end of one year and the beginning of another.\n\nTop New Year Activities in the UK include:\n\n* Attending a Hogmanay celebration in Scotland\n* Taking part in a local First-Foot tradition in Scotland and Northern England\n* Setting personal resolutions and goals for the upcoming year\n* Going for a New Year's Day walk to enjoy the fresh start\n* Visiting a local pub for a celebratory toast and some cheer\n`,\n\t\t},\n\t\t{\n\t\t\tDate:  time.Date(2023, time.May, 1, 0, 0, 0, 0, time.UTC),\n\t\t\tTitle: \"May Day\",\n\t\t\tContent: `May Day is an ancient spring festival celebrated on the first of May in the United Kingdom, embracing the arrival of warmer weather and the renewal of life.\n\nTop May Day Activities in the UK:\n\n* Dancing around the Maypole, a traditional folk activity\n* Attending local village fetes and fairs\n* Watching or participating in Morris dancing performances\n* Enjoying the day off as a public holiday, known as Early May Bank Holiday\n`,\n\t\t},\n\t}\n\n\t// Output path.\n\trootPath := \"public\"\n\tif err := os.Mkdir(rootPath, 0755); err != nil {\n\t\tlog.Fatalf(\"failed to create output directory: %v\", err)\n\t}\n\n\t// Create an index page.\n\tname := path.Join(rootPath, \"index.html\")\n\tf, err := os.Create(name)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create output file: %v\", err)\n\t}\n\t// Write it out.\n\terr = indexPage(posts).Render(context.Background(), f)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to write index page: %v\", err)\n\t}\n\n\t// Create a page for each post.\n\tfor _, post := range posts {\n\t\t// Create the output directory.\n\t\tdir := path.Join(rootPath, post.Date.Format(\"2006/01/02\"), slug.Make(post.Title))\n\t\tif err := os.MkdirAll(dir, 0755); err != nil && err != os.ErrExist {\n\t\t\tlog.Fatalf(\"failed to create dir %q: %v\", dir, err)\n\t\t}\n\n\t\t// Create the output file.\n\t\tname := path.Join(dir, \"index.html\")\n\t\tf, err := os.Create(name)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to create output file: %v\", err)\n\t\t}\n\n\t\t// Convert the markdown to HTML, and pass it to the template.\n\t\tvar buf bytes.Buffer\n\t\tif err := goldmark.Convert([]byte(post.Content), &buf); err != nil {\n\t\t\tlog.Fatalf(\"failed to convert markdown to HTML: %v\", err)\n\t\t}\n\n\t\t// Create an unsafe component containing raw HTML.\n\t\tcontent := Unsafe(buf.String())\n\n\t\t// Use templ to render the template containing the raw HTML.\n\t\terr = contentPage(post.Title, content).Render(context.Background(), f)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to write output file: %v\", err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/streaming/go.mod",
    "content": "module githbu.com/a-h/templ/examples/streaming\n\ngo 1.25.0\n\nreplace github.com/a-h/templ => ../../\n\nrequire github.com/a-h/templ v0.2.707\n"
  },
  {
    "path": "examples/streaming/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/streaming/main.templ",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc main() {\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Create a channel to send data to the template.\n\t\tdata := make(chan string)\n\t\t// Run a background process that will take 10 seconds to complete.\n\t\tgo func() {\n\t\t\t// Always remember to close the channel.\n\t\t\tdefer close(data)\n\t\t\tfor i := 0; i < 10; i++ {\n\t\t\t\tselect {\n\t\t\t\tcase <-r.Context().Done():\n\t\t\t\t\t// Quit early if the client is no longer connected.\n\t\t\t\t\treturn\n\t\t\t\tcase <-time.After(time.Second):\n\t\t\t\t\t// Send a new piece of data to the channel.\n\t\t\t\t\tdata <- fmt.Sprintf(\"Part %d\", i+1)\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\n\t\t// Pass the channel to the template.\n\t\tcomponent := Page(data)\n\n\t\t// Serve using the streaming mode of the handler.\n\t\ttempl.Handler(component, templ.WithStreaming()).ServeHTTP(w, r)\n\t})\n\thttp.ListenAndServe(\"127.0.0.1:8080\", nil)\n}\n\ntempl Page(data chan string) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<title>Page</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>Page</h1>\n\t\t\tfor d := range data {\n\t\t\t\t@templ.Flush() {\n\t\t\t\t\t<div>{ d }</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/streaming/main_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n)\n\nfunc main() {\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Create a channel to send data to the template.\n\t\tdata := make(chan string)\n\t\t// Run a background process that will take 10 seconds to complete.\n\t\tgo func() {\n\t\t\t// Always remember to close the channel.\n\t\t\tdefer close(data)\n\t\t\tfor i := 0; i < 10; i++ {\n\t\t\t\tselect {\n\t\t\t\tcase <-r.Context().Done():\n\t\t\t\t\t// Quit early if the client is no longer connected.\n\t\t\t\t\treturn\n\t\t\t\tcase <-time.After(time.Second):\n\t\t\t\t\t// Send a new piece of data to the channel.\n\t\t\t\t\tdata <- fmt.Sprintf(\"Part %d\", i+1)\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\n\t\t// Pass the channel to the template.\n\t\tcomponent := Page(data)\n\n\t\t// Serve using the streaming mode of the handler.\n\t\ttempl.Handler(component, templ.WithStreaming()).ServeHTTP(w, r)\n\t})\n\thttp.ListenAndServe(\"127.0.0.1:8080\", nil)\n}\n\nfunc Page(data chan string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype html><html><head><title>Page</title></head><body><h1>Page</h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor d := range data {\n\t\t\ttempl_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t}\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<div>\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(d)\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/streaming/main.templ`, Line: 48, Col: 13}\n\t\t\t\t}\n\t\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</div>\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\ttempl_7745c5c3_Err = templ.Flush().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/suspense/go.mod",
    "content": "module githbu.com/a-h/templ/examples/suspense\n\ngo 1.25.0\n\nreplace github.com/a-h/templ => ../../\n\nrequire github.com/a-h/templ v0.2.707\n"
  },
  {
    "path": "examples/suspense/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/suspense/main.templ",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc main() {\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Create a channel to send deferred component renders to the template.\n\t\tdata := make(chan SlotContents)\n\n\t\t// We know there are 3 slots, so start a WaitGroup.\n\t\tvar wg sync.WaitGroup\n\t\twg.Add(3)\n\n\t\t// Start the async processes.\n\t\t// Sidebar.\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\ttime.Sleep(time.Second * 3)\n\t\t\tdata <- SlotContents{\n\t\t\t\tName:     \"a\",\n\t\t\t\tContents: A(),\n\t\t\t}\n\t\t}()\n\n\t\t// Content.\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\ttime.Sleep(time.Second * 2)\n\t\t\tdata <- SlotContents{\n\t\t\t\tName:     \"b\",\n\t\t\t\tContents: B(),\n\t\t\t}\n\t\t}()\n\n\t\t// Footer.\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\ttime.Sleep(time.Second * 1)\n\t\t\tdata <- SlotContents{\n\t\t\t\tName:     \"c\",\n\t\t\t\tContents: C(),\n\t\t\t}\n\t\t}()\n\n\t\t// Close the channel when all processes are done.\n\t\tgo func() {\n\t\t\twg.Wait()\n\t\t\tclose(data)\n\t\t}()\n\n\t\t// Pass the channel to the template.\n\t\tcomponent := Page(data)\n\n\t\t// Serve using the streaming mode of the handler.\n\t\ttempl.Handler(component, templ.WithStreaming()).ServeHTTP(w, r)\n\t})\n\thttp.ListenAndServe(\"127.0.0.1:8080\", nil)\n}\n\ntype SlotContents struct {\n\tName     string\n\tContents templ.Component\n}\n\ntempl Slot(name string) {\n\t<slot name={ name }>\n\t\t<div>Loading { name }...</div>\n\t</slot>\n}\n\ntempl A() {\n\t<div>Component A.</div>\n}\n\ntempl B() {\n\t<div>Component B.</div>\n}\n\ntempl C() {\n\t<div>Component C.</div>\n}\n\ntempl Page(data chan SlotContents) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<title>Page</title>\n\t\t</head>\n\t\t<body>\n\t\t\t<h1>Page</h1>\n\t\t\t@templ.Flush() {\n\t\t\t\t<template shadowrootmode=\"open\">\n\t\t\t\t\t@Slot(\"a\")\n\t\t\t\t\t@Slot(\"b\")\n\t\t\t\t\t@Slot(\"c\")\n\t\t\t\t</template>\n\t\t\t}\n\t\t\tfor sc := range data {\n\t\t\t\t@templ.Flush() {\n\t\t\t\t\t<div slot={ sc.Name }>\n\t\t\t\t\t\t@sc.Contents\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/suspense/main_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport (\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n)\n\nfunc main() {\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Create a channel to send deferred component renders to the template.\n\t\tdata := make(chan SlotContents)\n\n\t\t// We know there are 3 slots, so start a WaitGroup.\n\t\tvar wg sync.WaitGroup\n\t\twg.Add(3)\n\n\t\t// Start the async processes.\n\t\t// Sidebar.\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\ttime.Sleep(time.Second * 3)\n\t\t\tdata <- SlotContents{\n\t\t\t\tName:     \"a\",\n\t\t\t\tContents: A(),\n\t\t\t}\n\t\t}()\n\n\t\t// Content.\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\ttime.Sleep(time.Second * 2)\n\t\t\tdata <- SlotContents{\n\t\t\t\tName:     \"b\",\n\t\t\t\tContents: B(),\n\t\t\t}\n\t\t}()\n\n\t\t// Footer.\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\ttime.Sleep(time.Second * 1)\n\t\t\tdata <- SlotContents{\n\t\t\t\tName:     \"c\",\n\t\t\t\tContents: C(),\n\t\t\t}\n\t\t}()\n\n\t\t// Close the channel when all processes are done.\n\t\tgo func() {\n\t\t\twg.Wait()\n\t\t\tclose(data)\n\t\t}()\n\n\t\t// Pass the channel to the template.\n\t\tcomponent := Page(data)\n\n\t\t// Serve using the streaming mode of the handler.\n\t\ttempl.Handler(component, templ.WithStreaming()).ServeHTTP(w, r)\n\t})\n\thttp.ListenAndServe(\"127.0.0.1:8080\", nil)\n}\n\ntype SlotContents struct {\n\tName     string\n\tContents templ.Component\n}\n\nfunc Slot(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<slot name=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/suspense/main.templ`, Line: 70, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\"><div>Loading \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/suspense/main.templ`, Line: 71, Col: 21}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"...</div></slot>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc A() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<div>Component A.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc B() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<div>Component B.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc C() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var6 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var6 == nil {\n\t\t\ttempl_7745c5c3_Var6 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<div>Component C.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc Page(data chan SlotContents) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var7 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var7 == nil {\n\t\t\ttempl_7745c5c3_Var7 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"<!doctype html><html><head><title>Page</title></head><body><h1>Page</h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<template shadowrootmode=\\\"open\\\">\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = Slot(\"a\").Render(ctx, templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = Slot(\"b\").Render(ctx, templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = Slot(\"c\").Render(ctx, templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"</template>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = templ.Flush().Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor sc := range data {\n\t\t\ttempl_7745c5c3_Var9 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t}\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"<div slot=\\\"\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\tvar templ_7745c5c3_Var10 string\n\t\t\t\ttempl_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(sc.Name)\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/suspense/main.templ`, Line: 104, Col: 24}\n\t\t\t\t}\n\t\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"\\\">\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\ttempl_7745c5c3_Err = sc.Contents.Render(ctx, templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"</div>\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\ttempl_7745c5c3_Err = templ.Flush().Render(templ.WithChildren(ctx, templ_7745c5c3_Var9), templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/syntax-and-usage/components/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"html\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\tif err := list([]string{\"a\", \"b\", \"c\"}).Render(ctx, os.Stdout); err != nil {\n\t\tlog.Fatalf(\"failed to render list: %v\", err)\n\t}\n\tif err := codeList([]string{\"A\", \"B\", \"C\"}).Render(ctx, os.Stdout); err != nil {\n\t\tlog.Fatalf(\"failed to render code list: %v\", err)\n\t}\n}\n\nfunc codeList(items []string) templ.Component {\n\treturn templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\tif _, err = io.WriteString(w, \"<ol>\"); err != nil {\n\t\t\treturn\n\t\t}\n\t\tfor _, item := range items {\n\t\t\tif _, err = io.WriteString(w, fmt.Sprintf(\"<li>%s</li>\", html.EscapeString(item))); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif _, err = io.WriteString(w, \"</ol>\"); err != nil {\n\t\t\treturn\n\t\t}\n\t\treturn nil\n\t})\n}\n"
  },
  {
    "path": "examples/syntax-and-usage/components/templsyntax.templ",
    "content": "package main\n\ntempl list(items []string) {\n\t<ol>\n\t\tfor _, item := range items {\n\t\t\t<li>{ item }</li>\n\t\t}\n\t</ol>\n}\n"
  },
  {
    "path": "examples/syntax-and-usage/components/templsyntax_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage main\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc list(items []string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<ol>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor _, item := range items {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<li>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(item)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/syntax-and-usage/components/templsyntax.templ`, Line: 6, Col: 13}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</li>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</ol>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/typescript/README.md",
    "content": "# Pass Go data to TypeScript\n\nThis demonstrates how to bundle TypeScript code, and use it in a templ project.\n\nThe TypeScript code is bundled using `esbuild`, with templ used to serve HTML.\n\nThe code demonstrates application of `onclick` event handlers, and how to pass data from Go to TypeScript.\n\nThis demo passes data from server-side Go code to TypeScript code by placing the data in `<script type=\"application/json\">` tags, or data attributes (called `alert-data` in this example).\n\nNote how the Go web server serves the `./assets` directory, which contains the bundled TypeScript code.\n\n## Tasks\n\n### generate\n\n```bash\ntempl generate\n```\n\n### ts-install\n\nSince it's a TypeScript project, you need to install the dependencies.\n\nDir: ts\n\n```bash\nnpm install\n```\n\n### ts-build-cli\n\nIf you have `esbuild` installed globally, you can bundle and minify the TypeScript code without using NPM. Remember to run `npm install` to install the dependencies first.\n\n```bash\nesbuild --bundle --minify --outfile=assets/js/index.js ts/src/index.ts\n```\n\n### ts-build-npm\n\nIf you don't have `esbuild` installed globally, you can use the NPM script to build the TypeScript code.\n\nDir: ./ts\n\n```bash\nnpm run build\n```\n\n### run\n\n```bash\ngo run .\n```\n"
  },
  {
    "path": "examples/typescript/assets/js/index.js",
    "content": "(()=>{function a(){let t=document.querySelector(\"#attributeAlerter\");t&&t.addEventListener(\"click\",n=>{let e=t?.getAttribute(\"alert-data\")??\"{}\",r=JSON.parse(e);alert(r.msg)})}function c(){let t=document.querySelector(\"#scriptAlerter\");t&&t.addEventListener(\"click\",n=>{let e=document?.getElementById(\"scriptData\")?.textContent??\"{}\",r=JSON.parse(e);alert(r.msg)})}a();c();})();\n"
  },
  {
    "path": "examples/typescript/components/index.templ",
    "content": "package components\n\ntype Data struct {\n\tMessage string `json:\"msg\"`\n}\n\ntempl Page(attributeData Data, scriptData Data) {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<head>\n\t\t\t<title>Script usage</title>\n\t\t\t<script src=\"/assets/js/index.js\" defer></script>\n\t\t</head>\n\t\t<body>\n\t\t\t<button id=\"attributeAlerter\" alert-data={ templ.JSONString(attributeData) }>Show alert from data in alert-data attribute</button>\n\t\t\t@templ.JSONScript(\"scriptData\", scriptData)\n\t\t\t<button id=\"scriptAlerter\">Show alert from data in script</button>\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "examples/typescript/components/index_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage components\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\ntype Data struct {\n\tMessage string `json:\"msg\"`\n}\n\nfunc Page(attributeData Data, scriptData Data) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype html><html><head><title>Script usage</title><script src=\\\"/assets/js/index.js\\\" defer></script></head><body><button id=\\\"attributeAlerter\\\" alert-data=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(templ.JSONString(attributeData))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `examples/typescript/components/index.templ`, Line: 15, Col: 77}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">Show alert from data in alert-data attribute</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.JSONScript(\"scriptData\", scriptData).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<button id=\\\"scriptAlerter\\\">Show alert from data in script</button></body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "examples/typescript/go.mod",
    "content": "module github.com/a-h/templ/examples/typescript\n\ngo 1.25.0\n\nreplace github.com/a-h/templ => ../../\n\nrequire github.com/a-h/templ v0.0.0-00010101000000-000000000000\n"
  },
  {
    "path": "examples/typescript/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\n"
  },
  {
    "path": "examples/typescript/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/examples/typescript/components\"\n)\n\nfunc main() {\n\tmux := http.NewServeMux()\n\t// Serve the JS bundle.\n\tmux.Handle(\"/assets/\", http.StripPrefix(\"/assets/\", http.FileServer(http.Dir(\"assets\"))))\n\n\t// Serve the page.\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Create random server-side data.\n\t\tattributeData := components.Data{\n\t\t\tMessage: fmt.Sprintf(\"Hello, from the attribute data\"),\n\t\t}\n\t\tscriptData := components.Data{\n\t\t\tMessage: fmt.Sprintf(\"Hello, from the script data\"),\n\t\t}\n\t\ttempl.Handler(components.Page(attributeData, scriptData)).ServeHTTP(w, r)\n\t})\n\n\tfmt.Println(\"Listening on http://localhost:8080\")\n\thttp.ListenAndServe(\"localhost:8080\", mux)\n}\n"
  },
  {
    "path": "examples/typescript/ts/package.json",
    "content": "{\n  \"name\": \"ts\",\n  \"version\": \"1.0.0\",\n  \"description\": \"TypeScript templ example.\",\n  \"scripts\": {\n    \"build\": \"esbuild --bundle --minify --outfile=../assets/js/index.js ./src/index.ts\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"esbuild\": \"0.25.0\",\n    \"typescript\": \"^5.4.5\"\n  }\n}\n"
  },
  {
    "path": "examples/typescript/ts/src/index.ts",
    "content": "// You can use npm install to add additional packages.\n// And import them in this file.\n// esbuild will bundle them into the final output.\n\ninterface Data {\n\tmsg: string;\n}\n\nfunction setupAttributeAlerter() {\n\tconst alerter = document.querySelector(\"#attributeAlerter\");\n\tif (!alerter) {\n\t\treturn;\n\t}\n\talerter.addEventListener(\"click\", (_event: Event) => {\n\t\tconst dataAttr = alerter?.getAttribute('alert-data') ?? '{}';\n\t\tconst data: Data = JSON.parse(dataAttr);\n\t\talert(data.msg);\n\t})\n}\n\nfunction setupScriptAlerter() {\n\tconst alerter = document.querySelector(\"#scriptAlerter\");\n\tif (!alerter) {\n\t\treturn;\n\t}\n\talerter.addEventListener(\"click\", (_event: Event) => {\n\t\tconst dataContent = document?.getElementById('scriptData')?.textContent ?? '{}';\n\t\tconst data: Data = JSON.parse(dataContent);\n\t\talert(data.msg);\n\t})\n}\n\nsetupAttributeAlerter();\nsetupScriptAlerter();\n"
  },
  {
    "path": "flake.nix",
    "content": "{\n  description = \"templ\";\n\n  inputs = {\n    nixpkgs.url = \"github:NixOS/nixpkgs/nixos-25.11\";\n    nixpkgs-unstable.url = \"github:NixOS/nixpkgs/nixos-unstable\";\n    gitignore = {\n      url = \"github:hercules-ci/gitignore.nix\";\n      inputs.nixpkgs.follows = \"nixpkgs\";\n    };\n    version = {\n      url = \"github:a-h/version/0.0.10\";\n      inputs.nixpkgs.follows = \"nixpkgs\";\n    };\n  };\n\n  outputs = { self, nixpkgs, nixpkgs-unstable, gitignore, version }:\n    let\n      allSystems = [\n        \"x86_64-linux\" # 64-bit Intel/AMD Linux\n        \"aarch64-linux\" # 64-bit ARM Linux\n        \"x86_64-darwin\" # 64-bit Intel macOS\n        \"aarch64-darwin\" # 64-bit ARM macOS\n      ];\n      forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {\n        inherit system;\n        pkgs =\n          let\n            pkgs-unstable = import nixpkgs-unstable { inherit system; };\n          in\n          import nixpkgs {\n            inherit system;\n            overlays = [\n              (final: prev: {\n                gopls = pkgs-unstable.gopls;\n                version = version.packages.${system}.default; # Used to apply version numbers to the repo.\n              })\n            ];\n          };\n      });\n    in\n    {\n      packages = forAllSystems ({ pkgs, ... }:\n        rec {\n          default = templ;\n\n          templ = pkgs.buildGoModule {\n            name = \"templ\";\n            subPackages = [ \"cmd/templ\" ];\n            src = gitignore.lib.gitignoreSource ./.;\n            vendorHash = \"sha256-i4uDGZb3VZUvIyO2Tt53VR1Do/3OYtj6JccGoFnnlbs=\";\n            env = {\n              CGO_ENABLED = 0;\n            };\n            flags = [\n              \"-trimpath\"\n            ];\n            ldflags = [\n              \"-s\"\n              \"-w\"\n              \"-extldflags -static\"\n            ];\n          };\n        });\n\n      # `nix develop` provides a shell containing development tools.\n      devShell = forAllSystems ({ pkgs, ... }:\n        pkgs.mkShell {\n          buildInputs = [\n            pkgs.golangci-lint\n            pkgs.cosign # Used to sign container images.\n            pkgs.esbuild # Used to package JS examples.\n            pkgs.go\n            pkgs.gopls\n            pkgs.goreleaser\n            pkgs.gotestsum\n            pkgs.govulncheck\n            pkgs.ko # Used to build Docker images.\n            pkgs.nodejs # Used to build templ-docs.\n            pkgs.nodePackages.prettier # Used for formatting JS and CSS.\n            pkgs.version\n            pkgs.xc\n          ];\n        });\n\n      # This flake outputs an overlay that can be used to add templ and\n      # templ-docs to nixpkgs as per https://templ.guide/quick-start/installation/#nix\n      #\n      # Example usage:\n      #\n      # nixpkgs.overlays = [\n      #   inputs.templ.overlays.default\n      # ];\n      overlays.default = final: prev: {\n        templ = self.packages.${final.stdenv.system}.templ;\n      };\n    };\n}\n\n"
  },
  {
    "path": "flush.go",
    "content": "package templ\n\nimport (\n\t\"context\"\n\t\"io\"\n)\n\n// Flush flushes the output buffer after all its child components have been rendered.\nfunc Flush() FlushComponent {\n\treturn FlushComponent{}\n}\n\ntype FlushComponent struct {\n}\n\ntype flusherError interface {\n\tFlush() error\n}\n\ntype flusher interface {\n\tFlush()\n}\n\nfunc (f FlushComponent) Render(ctx context.Context, w io.Writer) (err error) {\n\tif err = GetChildren(ctx).Render(ctx, w); err != nil {\n\t\treturn err\n\t}\n\tswitch w := w.(type) {\n\tcase flusher:\n\t\tw.Flush()\n\t\treturn nil\n\tcase flusherError:\n\t\treturn w.Flush()\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "flush_test.go",
    "content": "package templ\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n)\n\ntype flushableErrorWriter struct {\n\tlastFlushPos    int\n\tpos             int\n\tsb              strings.Builder\n\tflushedSections []string\n}\n\nfunc (f *flushableErrorWriter) Write(p []byte) (n int, err error) {\n\tn, err = f.sb.Write(p)\n\tif err != nil {\n\t\treturn\n\t}\n\tif n < len(p) {\n\t\terr = io.ErrShortWrite\n\t}\n\tf.pos += n\n\treturn\n}\n\nfunc (f *flushableErrorWriter) Flush() error {\n\tf.flushedSections = append(f.flushedSections, f.sb.String()[f.lastFlushPos:f.pos])\n\tf.lastFlushPos = f.pos\n\treturn nil\n}\n\ntype flushableWriter struct {\n\tlastFlushPos    int\n\tpos             int\n\tsb              strings.Builder\n\tflushedSections []string\n}\n\nfunc (f *flushableWriter) Write(p []byte) (n int, err error) {\n\tn, err = f.sb.Write(p)\n\tif err != nil {\n\t\treturn\n\t}\n\tif n < len(p) {\n\t\terr = io.ErrShortWrite\n\t}\n\tf.pos += n\n\treturn\n}\n\nfunc (f *flushableWriter) Flush() {\n\tf.flushedSections = append(f.flushedSections, f.sb.String()[f.lastFlushPos:f.pos])\n\tf.lastFlushPos = f.pos\n}\n\nfunc TestFlush(t *testing.T) {\n\tt.Run(\"errors in child components are propagated\", func(t *testing.T) {\n\t\texpectedErr := fmt.Errorf(\"test error\")\n\t\tchild := ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\treturn expectedErr\n\t\t})\n\n\t\tsb := new(strings.Builder)\n\t\tctx := WithChildren(context.Background(), child)\n\n\t\terr := Flush().Render(ctx, sb)\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"expected an error, got nil\")\n\t\t}\n\t\tif err != expectedErr {\n\t\t\tt.Fatalf(\"expected error to be %v, got %v\", expectedErr, err)\n\t\t}\n\t})\n\tt.Run(\"can render to a flushable error writer\", func(t *testing.T) {\n\t\tchild := ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\t_, err := w.Write([]byte(\"hello\"))\n\t\t\treturn err\n\t\t})\n\n\t\tb := &flushableErrorWriter{}\n\t\tctx := WithChildren(context.Background(), child)\n\n\t\t// Render the FlushComponent to the buffer\n\t\tif err := Flush().Render(ctx, b); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\tif len(b.flushedSections) != 1 {\n\t\t\tt.Fatalf(\"expected 1 flushed section, got %d\", len(b.flushedSections))\n\t\t}\n\t\tif b.flushedSections[0] != \"hello\" {\n\t\t\tt.Fatalf(\"expected flushed section to be 'hello', got %q\", b.flushedSections[0])\n\t\t}\n\t})\n\tt.Run(\"can render to a flushable writer\", func(t *testing.T) {\n\t\tchild := ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\t_, err := w.Write([]byte(\"hello\"))\n\t\t\treturn err\n\t\t})\n\n\t\tb := &flushableWriter{}\n\t\tctx := WithChildren(context.Background(), child)\n\n\t\t// Render the FlushComponent to the buffer\n\t\tif err := Flush().Render(ctx, b); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\n\t\tif len(b.flushedSections) != 1 {\n\t\t\tt.Fatalf(\"expected 1 flushed section, got %d\", len(b.flushedSections))\n\t\t}\n\t\tif b.flushedSections[0] != \"hello\" {\n\t\t\tt.Fatalf(\"expected flushed section to be 'hello', got %q\", b.flushedSections[0])\n\t\t}\n\t})\n\tt.Run(\"non-flushable streams are a no-op\", func(t *testing.T) {\n\t\tsb := new(strings.Builder)\n\t\tif err := Flush().Render(context.Background(), sb); err != nil {\n\t\t\tt.Fatalf(\"expected no error, got %v\", err)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "fragment.go",
    "content": "package templ\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"slices\"\n)\n\n// RenderFragments renders the specified fragments to w.\nfunc RenderFragments(ctx context.Context, w io.Writer, c Component, ids ...any) error {\n\tctx = context.WithValue(ctx, fragmentContextKey, &FragmentContext{\n\t\tW:   w,\n\t\tIDs: ids,\n\t})\n\treturn c.Render(ctx, io.Discard)\n}\n\ntype fragmentContextKeyType int\n\nconst fragmentContextKey fragmentContextKeyType = iota\n\n// FragmentContext is used to control rendering of fragments within a template.\ntype FragmentContext struct {\n\tW      io.Writer\n\tIDs    []any\n\tActive bool\n}\n\n// Fragment defines a fragment within a template that can be rendered conditionally based on the id.\n// You can use it to render a specific part of a page, e.g. to reduce the amount of HTML returned from a htmx-initiated request.\n// Any non-matching contents of the template are rendered, but discarded by the FramentWriter.\nfunc Fragment(id any) Component {\n\treturn &fragment{\n\t\tID: id,\n\t}\n}\n\ntype fragment struct {\n\tID any\n}\n\nfunc (f *fragment) Render(ctx context.Context, w io.Writer) (err error) {\n\t// If not in a fragment context, if we're a child fragment, or in a mismatching fragment context, render children normally.\n\tfragmentCtx := getFragmentContext(ctx)\n\tif fragmentCtx == nil || fragmentCtx.Active || !slices.Contains(fragmentCtx.IDs, f.ID) {\n\t\treturn GetChildren(ctx).Render(ctx, w)\n\t}\n\n\t// Instruct child fragments to render their contents normally, because the writer\n\t// passed to them is already the FragmentContext's writer.\n\tfragmentCtx.Active = true\n\tdefer func() {\n\t\tfragmentCtx.Active = false\n\t}()\n\treturn GetChildren(ctx).Render(ctx, fragmentCtx.W)\n}\n\n// getFragmentContext retrieves the FragmentContext from the provided context. It returns nil if no\n// FragmentContext is found or if the context value is of an unexpected type.\nfunc getFragmentContext(ctx context.Context) *FragmentContext {\n\tctxValue := ctx.Value(fragmentContextKey)\n\tif ctxValue == nil {\n\t\treturn nil\n\t}\n\tv, ok := ctxValue.(*FragmentContext)\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn v\n}\n"
  },
  {
    "path": "fragment_test.go",
    "content": "package templ_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc TestFragment(t *testing.T) {\n\tfragmentPage := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\tif _, err := io.WriteString(w, \"page_contents\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfragmentContents := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\t_, err := io.WriteString(w, \"fragment_contents\")\n\t\t\treturn err\n\t\t})\n\t\treturn templ.Fragment(\"fragment\").Render(templ.WithChildren(ctx, fragmentContents), w)\n\t})\n\tt.Run(\"can render without a HTTP handler\", func(t *testing.T) {\n\t\tw := new(bytes.Buffer)\n\t\tif err := templ.RenderFragments(context.Background(), w, fragmentPage, \"fragment\"); err != nil {\n\t\t\tt.Fatalf(\"failed to render: %v\", err)\n\t\t}\n\n\t\t// Note that the fragment should have been written to the output.\n\t\tif w.String() != \"fragment_contents\" {\n\t\t\tt.Errorf(\"expected output 'fragment_contents', got '%s'\", w.String())\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "generator/generator.go",
    "content": "package generator\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"html\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode\"\n\n\t_ \"embed\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\ntype GenerateOpt func(g *generator) error\n\n// WithVersion enables the version to be included in the generated code.\nfunc WithVersion(v string) GenerateOpt {\n\treturn func(g *generator) error {\n\t\tg.options.Version = v\n\t\treturn nil\n\t}\n}\n\n// WithTimestamp enables the generated date to be included in the generated code.\nfunc WithTimestamp(d time.Time) GenerateOpt {\n\treturn func(g *generator) error {\n\t\tg.options.GeneratedDate = d.Format(time.RFC3339)\n\t\treturn nil\n\t}\n}\n\n// WithFileName sets the filename of the templ file in template rendering error messages.\nfunc WithFileName(name string) GenerateOpt {\n\treturn func(g *generator) error {\n\t\tif filepath.IsAbs(name) {\n\t\t\t_, g.options.FileName = filepath.Split(name)\n\t\t\treturn nil\n\t\t}\n\t\tg.options.FileName = name\n\t\treturn nil\n\t}\n}\n\n// WithSkipCodeGeneratedComment skips the code generated comment at the top of the file.\n// gopls disables edit related functionality for generated files, so the templ LSP may\n// wish to skip generation of this comment so that gopls provides expected results.\nfunc WithSkipCodeGeneratedComment() GenerateOpt {\n\treturn func(g *generator) error {\n\t\tg.options.SkipCodeGeneratedComment = true\n\t\treturn nil\n\t}\n}\n\ntype GeneratorOutput struct {\n\tOptions   GeneratorOptions  `json:\"meta\"`\n\tSourceMap *parser.SourceMap `json:\"sourceMap\"`\n\tLiterals  []string          `json:\"literals\"`\n}\n\ntype GeneratorOptions struct {\n\t// Version of templ.\n\tVersion string\n\t// FileName to include in error messages if string expressions return an error.\n\tFileName string\n\t// SkipCodeGeneratedComment skips the code generated comment at the top of the file.\n\tSkipCodeGeneratedComment bool\n\t// GeneratedDate to include as a comment.\n\tGeneratedDate string\n}\n\n// HasGoChanged returns true if the Go code has changed between the previous and updated GeneratorOutput.\nfunc HasGoChanged(previous, updated GeneratorOutput) bool {\n\t// If generator options have changed, we need to recompile.\n\tif previous.Options.Version != updated.Options.Version {\n\t\treturn true\n\t}\n\tif previous.Options.FileName != updated.Options.FileName {\n\t\treturn true\n\t}\n\tif previous.Options.SkipCodeGeneratedComment != updated.Options.SkipCodeGeneratedComment {\n\t\treturn true\n\t}\n\t// We don't check the generated date as it's not used for determining if the file has changed.\n\t// If the number of literals has changed, we need to recompile.\n\tif len(previous.Literals) != len(updated.Literals) {\n\t\treturn true\n\t}\n\t// If the Go code has changed, we need to recompile.\n\tif len(previous.SourceMap.Expressions) != len(updated.SourceMap.Expressions) {\n\t\treturn true\n\t}\n\tfor i, prev := range previous.SourceMap.Expressions {\n\t\tif prev != updated.SourceMap.Expressions[i] {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// HasTextChanged returns true if the text literals have changed between the previous and updated GeneratorOutput.\nfunc HasTextChanged(previous, updated GeneratorOutput) bool {\n\tif len(previous.Literals) != len(updated.Literals) {\n\t\treturn true\n\t}\n\tfor i, prev := range previous.Literals {\n\t\tif prev != updated.Literals[i] {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Generate generates Go code from the input template file to w, and returns a map of the location of Go expressions in the template\n// to the location of the generated Go code in the output.\nfunc Generate(template *parser.TemplateFile, w io.Writer, opts ...GenerateOpt) (op GeneratorOutput, err error) {\n\tg := &generator{\n\t\ttf:        template,\n\t\tw:         NewRangeWriter(w),\n\t\tsourceMap: parser.NewSourceMap(),\n\t}\n\tfor _, opt := range opts {\n\t\tif err = opt(g); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\terr = g.generate()\n\tif err != nil {\n\t\treturn op, err\n\t}\n\top.Options = g.options\n\top.SourceMap = g.sourceMap\n\top.Literals = g.w.Literals\n\treturn op, nil\n}\n\ntype generator struct {\n\ttf          *parser.TemplateFile\n\tw           *RangeWriter\n\tsourceMap   *parser.SourceMap\n\tvariableID  int\n\tchildrenVar string\n\n\toptions GeneratorOptions\n}\n\nfunc (g *generator) generate() (err error) {\n\tif err = g.writeCodeGeneratedComment(); err != nil {\n\t\treturn\n\t}\n\tif err = g.writeVersionComment(); err != nil {\n\t\treturn\n\t}\n\tif err = g.writeGeneratedDateComment(); err != nil {\n\t\treturn\n\t}\n\tif err = g.writeHeader(); err != nil {\n\t\treturn\n\t}\n\tif err = g.writePackage(); err != nil {\n\t\treturn\n\t}\n\tif err = g.writeImports(); err != nil {\n\t\treturn\n\t}\n\tif err = g.writeTemplateNodes(); err != nil {\n\t\treturn\n\t}\n\tif err = g.writeBlankAssignmentForRuntimeImport(); err != nil {\n\t\treturn\n\t}\n\treturn err\n}\n\n// See https://pkg.go.dev/cmd/go#hdr-Generate_Go_files_by_processing_source\n// Automatically generated files have a comment in the header that instructs the LSP\n// to stop operating.\nfunc (g *generator) writeCodeGeneratedComment() (err error) {\n\tif g.options.SkipCodeGeneratedComment {\n\t\t// Write an empty comment so that the file is the same shape.\n\t\t_, err = g.w.Write(\"//\\n\\n\")\n\t\treturn err\n\t}\n\t_, err = g.w.Write(\"// Code generated by templ - DO NOT EDIT.\\n\\n\")\n\treturn err\n}\n\nfunc (g *generator) writeVersionComment() (err error) {\n\tif g.options.Version != \"\" {\n\t\t_, err = g.w.Write(\"// templ: version: \" + g.options.Version + \"\\n\")\n\t}\n\treturn err\n}\n\nfunc (g *generator) writeGeneratedDateComment() (err error) {\n\tif g.options.GeneratedDate != \"\" {\n\t\t_, err = g.w.Write(\"// templ: generated: \" + g.options.GeneratedDate + \"\\n\")\n\t}\n\treturn err\n}\n\nfunc (g *generator) writeHeader() (err error) {\n\tif len(g.tf.Header) == 0 {\n\t\treturn nil\n\t}\n\tfor _, n := range g.tf.Header {\n\t\tif err := g.writeGoExpression(n); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn err\n}\n\nfunc (g *generator) writePackage() error {\n\tvar r parser.Range\n\tvar err error\n\t// package ...\n\tif r, err = g.w.Write(g.tf.Package.Expression.Value + \"\\n\\n\"); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(g.tf.Package.Expression, r)\n\tif _, err = g.w.Write(\"//lint:file-ignore SA4006 This context is only used if a nested component is present.\\n\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeImports() error {\n\tvar err error\n\t// Always import templ because it's the interface type of all templates.\n\tif _, err = g.w.Write(\"import \\\"github.com/a-h/templ\\\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif _, err = g.w.Write(\"import templruntime \\\"github.com/a-h/templ/runtime\\\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif _, err = g.w.Write(\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeTemplateNodes() error {\n\tfor i, n := range g.tf.Nodes {\n\t\tswitch n := n.(type) {\n\t\tcase *parser.TemplateFileGoExpression:\n\t\t\tif err := g.writeGoExpression(n); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase *parser.HTMLTemplate:\n\t\t\tif err := g.writeTemplate(i, n); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase *parser.CSSTemplate:\n\t\t\tif err := g.writeCSS(n); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase *parser.ScriptTemplate:\n\t\t\tif err := g.writeScript(n); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown node type: %v\", reflect.TypeOf(n))\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeCSS(n *parser.CSSTemplate) error {\n\tif n == nil {\n\t\treturn errors.New(\"CSS template is nil\")\n\t}\n\tvar r parser.Range\n\tvar tgtSymbolRange parser.Range\n\tvar err error\n\tvar indentLevel int\n\n\t// func\n\tif r, err = g.w.Write(\"func \"); err != nil {\n\t\treturn err\n\t}\n\ttgtSymbolRange.From = r.From\n\tif r, err = g.w.Write(n.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(n.Expression, r)\n\t// templ.CSSClass {\n\tif _, err = g.w.Write(\" templ.CSSClass {\\n\"); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindentLevel++\n\t\t// templ_7745c5c3_CSSBuilder := templruntim.GetBuilder()\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, p := range n.Properties {\n\t\t\tswitch p := p.(type) {\n\t\t\tcase *parser.ConstantCSSProperty:\n\t\t\t\t// Constant CSS property values are not sanitized.\n\t\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_CSSBuilder.WriteString(\"+createGoString(p.String(true))+\")\\n\"); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\tcase *parser.ExpressionCSSProperty:\n\t\t\t\t// templ_7745c5c3_CSSBuilder.WriteString(templ.SanitizeCSS('name', p.Expression()))\n\t\t\t\tif _, err = g.w.WriteIndent(indentLevel, fmt.Sprintf(\"templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`%s`, \", p.Name)); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif r, err = g.w.Write(p.Value.Expression.Value); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tg.sourceMap.Add(p.Value.Expression, r)\n\t\t\t\tif _, err = g.w.Write(\")))\\n\"); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"unknown CSS property type: %v\", reflect.TypeOf(p))\n\t\t\t}\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, fmt.Sprintf(\"templ_7745c5c3_CSSID := templ.CSSID(`%s`, templ_7745c5c3_CSSBuilder.String())\\n\", n.Name)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// return templ.CSS {\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"return templ.ComponentCSSClass{\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t{\n\t\t\tindentLevel++\n\t\t\t// ID: templ_7745c5c3_CSSID,\n\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"ID: templ_7745c5c3_CSSID,\\n\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// Class: templ.SafeCSS(\".cssID{\" + templ.CSSBuilder.String() + \"}\"),\n\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\\n\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"}\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindentLevel--\n\t}\n\t// }\n\tif r, err = g.w.WriteIndent(indentLevel, \"}\\n\\n\"); err != nil {\n\t\treturn err\n\t}\n\n\t// Keep a track of symbol ranges for the LSP.\n\ttgtSymbolRange.To = r.To\n\tg.sourceMap.AddSymbolRange(n.Range, tgtSymbolRange)\n\n\treturn nil\n}\n\nfunc (g *generator) writeGoExpression(n *parser.TemplateFileGoExpression) (err error) {\n\tif n == nil {\n\t\treturn errors.New(\"go expression is nil\")\n\t}\n\tvar tgtSymbolRange parser.Range\n\n\tr, err := g.w.Write(n.Expression.Value)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttgtSymbolRange.From = r.From\n\tg.sourceMap.Add(n.Expression, r)\n\tv := n.Expression.Value\n\tlineSlice := strings.Split(v, \"\\n\")\n\tlastLine := lineSlice[len(lineSlice)-1]\n\tif strings.HasPrefix(lastLine, \"//\") {\n\t\tif _, err = g.w.WriteIndent(0, \"\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn err\n\t}\n\tif r, err = g.w.WriteIndent(0, \"\\n\\n\"); err != nil {\n\t\treturn err\n\t}\n\n\t// Keep a track of symbol ranges for the LSP.\n\ttgtSymbolRange.To = r.To\n\tg.sourceMap.AddSymbolRange(n.Expression.Range, tgtSymbolRange)\n\n\treturn err\n}\n\nfunc (g *generator) writeTemplBuffer(indentLevel int) (err error) {\n\t// templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// if !templ_7745c5c3_IsBuffer {\n\t//\tdefer func() {\n\t//\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t//\t\tif templ_7745c5c3_Err == nil {\n\t//\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t//\t\t}\n\t//\t}()\n\t// }\n\tif _, err = g.w.WriteIndent(indentLevel, \"if !templ_7745c5c3_IsBuffer {\\n\"); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindentLevel++\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"defer func() {\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t{\n\t\t\tindentLevel++\n\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\\n\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"if templ_7745c5c3_Err == nil {\\n\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t{\n\t\t\t\tindentLevel++\n\t\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_Err = templ_7745c5c3_BufErr\\n\"); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tindentLevel--\n\t\t\t}\n\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"}\\n\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"}()\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindentLevel--\n\t}\n\tif _, err = g.w.WriteIndent(indentLevel, \"}\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn\n}\n\nfunc (g *generator) writeTemplate(nodeIdx int, t *parser.HTMLTemplate) error {\n\tif t == nil {\n\t\treturn errors.New(\"template is nil\")\n\t}\n\tvar r parser.Range\n\tvar tgtSymbolRange parser.Range\n\tvar err error\n\tvar indentLevel int\n\n\t// func\n\tif r, err = g.w.Write(\"func \"); err != nil {\n\t\treturn err\n\t}\n\ttgtSymbolRange.From = r.From\n\t// (r *Receiver) Name(params []string)\n\tif r, err = g.w.Write(t.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(t.Expression, r)\n\t// templ.Component {\n\tif _, err = g.w.Write(\" templ.Component {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindentLevel++\n\t// return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\tif _, err = g.w.WriteIndent(indentLevel, \"return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\\n\"); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindentLevel++\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t{\n\t\t\tindentLevel++\n\t\t\tif _, err = g.w.WriteIndent(indentLevel, \"return templ_7745c5c3_CtxErr\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"}\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := g.writeTemplBuffer(indentLevel); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// ctx = templ.InitializeContext(ctx)\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"ctx = templ.InitializeContext(ctx)\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tg.childrenVar = g.createVariableName()\n\t\t// templ_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\t// if templ_7745c5c3_Var1 == nil {\n\t\t//  \ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t// }\n\t\tif _, err = g.w.WriteIndent(indentLevel, fmt.Sprintf(\"%s := templ.GetChildren(ctx)\\n\", g.childrenVar)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, fmt.Sprintf(\"if %s == nil {\\n\", g.childrenVar)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t{\n\t\t\tindentLevel++\n\t\t\tif _, err = g.w.WriteIndent(indentLevel, fmt.Sprintf(\"%s = templ.NopComponent\\n\", g.childrenVar)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"}\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// ctx = templ.ClearChildren(children)\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"ctx = templ.ClearChildren(ctx)\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Nodes.\n\t\tif err = g.writeNodes(indentLevel, stripWhitespace(t.Children), nil); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// return nil\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"return nil\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindentLevel--\n\t}\n\t// })\n\tif _, err = g.w.WriteIndent(indentLevel, \"})\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindentLevel--\n\t// }\n\n\t// Note: gofmt wants to remove a single empty line at the end of a file\n\t// so we have to make sure we don't output one if this is the last node.\n\tclosingBrace := \"}\\n\\n\"\n\tif nodeIdx+1 >= len(g.tf.Nodes) {\n\t\tclosingBrace = \"}\\n\"\n\t}\n\n\tif r, err = g.w.WriteIndent(indentLevel, closingBrace); err != nil {\n\t\treturn err\n\t}\n\n\t// Keep a track of symbol ranges for the LSP.\n\ttgtSymbolRange.To = r.To\n\tg.sourceMap.AddSymbolRange(t.Range, tgtSymbolRange)\n\n\treturn nil\n}\n\nfunc stripWhitespace(input []parser.Node) (output []parser.Node) {\n\tfor i, n := range input {\n\t\tif _, isWhiteSpace := n.(*parser.Whitespace); !isWhiteSpace {\n\t\t\toutput = append(output, input[i])\n\t\t}\n\t}\n\treturn output\n}\n\nfunc stripLeadingWhitespace(nodes []parser.Node) []parser.Node {\n\tfor i, n := range nodes {\n\t\tif _, isWhiteSpace := n.(*parser.Whitespace); !isWhiteSpace {\n\t\t\treturn nodes[i:]\n\t\t}\n\t}\n\treturn []parser.Node{}\n}\n\nfunc stripTrailingWhitespace(nodes []parser.Node) []parser.Node {\n\tfor i := len(nodes) - 1; i >= 0; i-- {\n\t\tn := nodes[i]\n\t\tif _, isWhiteSpace := n.(*parser.Whitespace); !isWhiteSpace {\n\t\t\treturn nodes[0 : i+1]\n\t\t}\n\t}\n\treturn []parser.Node{}\n}\n\nfunc stripLeadingAndTrailingWhitespace(nodes []parser.Node) []parser.Node {\n\treturn stripTrailingWhitespace(stripLeadingWhitespace(nodes))\n}\n\nfunc (g *generator) writeNodes(indentLevel int, nodes []parser.Node, next parser.Node) error {\n\tfor i, curr := range nodes {\n\t\tvar nextNode parser.Node\n\t\tif i+1 < len(nodes) {\n\t\t\tnextNode = nodes[i+1]\n\t\t}\n\t\tif nextNode == nil {\n\t\t\tnextNode = next\n\t\t}\n\t\tif err := g.writeNode(indentLevel, curr, nextNode); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeNode(indentLevel int, current parser.Node, next parser.Node) (err error) {\n\tswitch n := current.(type) {\n\tcase *parser.DocType:\n\t\terr = g.writeDocType(indentLevel, n)\n\tcase *parser.Element:\n\t\terr = g.writeElement(indentLevel, n)\n\tcase *parser.HTMLComment:\n\t\terr = g.writeComment(indentLevel, n)\n\tcase *parser.ChildrenExpression:\n\t\terr = g.writeChildrenExpression(indentLevel)\n\tcase *parser.RawElement:\n\t\terr = g.writeRawElement(indentLevel, n)\n\tcase *parser.ScriptElement:\n\t\terr = g.writeScriptElement(indentLevel, n)\n\tcase *parser.ForExpression:\n\t\terr = g.writeForExpression(indentLevel, n, next)\n\tcase *parser.CallTemplateExpression:\n\t\terr = g.writeCallTemplateExpression(indentLevel, n)\n\tcase *parser.TemplElementExpression:\n\t\terr = g.writeTemplElementExpression(indentLevel, n)\n\tcase *parser.IfExpression:\n\t\terr = g.writeIfExpression(indentLevel, n, next)\n\tcase *parser.SwitchExpression:\n\t\terr = g.writeSwitchExpression(indentLevel, n, next)\n\tcase *parser.StringExpression:\n\t\terr = g.writeStringExpression(indentLevel, n.Expression)\n\tcase *parser.GoCode:\n\t\terr = g.writeGoCode(indentLevel, n.Expression)\n\tcase *parser.Whitespace:\n\t\terr = g.writeWhitespace(indentLevel, n)\n\tcase *parser.Text:\n\t\terr = g.writeText(indentLevel, n)\n\tcase *parser.Fallthrough:\n\t\terr = g.writeFallthrough(indentLevel)\n\tcase *parser.GoComment:\n\t\t// Do not render Go comments in the output HTML.\n\t\treturn\n\tdefault:\n\t\treturn fmt.Errorf(\"unhandled type: %v\", reflect.TypeOf(n))\n\t}\n\t// Write trailing whitespace, if there is a next node that might need the space.\n\t// If the next node is inline or text, we might need it.\n\t// If the current node is a block element, we don't need it.\n\tneeded := (isInlineOrText(current) && isInlineOrText(next))\n\tif ws, ok := current.(parser.WhitespaceTrailer); ok && needed {\n\t\tif err := g.writeWhitespaceTrailer(indentLevel, ws.Trailing()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn\n}\n\nfunc isInlineOrText(next parser.Node) bool {\n\t// While these are formatted as blocks when they're written in the HTML template.\n\t// They're inline - i.e. there's no whitespace rendered around them at runtime for minification.\n\tif next == nil {\n\t\treturn false\n\t}\n\tswitch n := next.(type) {\n\tcase *parser.IfExpression:\n\t\treturn true\n\tcase *parser.SwitchExpression:\n\t\treturn true\n\tcase *parser.ForExpression:\n\t\treturn true\n\tcase *parser.Element:\n\t\treturn !n.IsBlockElement()\n\tcase *parser.Text:\n\t\treturn true\n\tcase *parser.StringExpression:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (g *generator) writeWhitespaceTrailer(indentLevel int, n parser.TrailingSpace) (err error) {\n\tif n == parser.SpaceNone {\n\t\treturn nil\n\t}\n\t// Normalize whitespace for minified output. In HTML, a single space is equivalent to\n\t// any number of spaces, tabs, or newlines.\n\tif n == parser.SpaceVertical {\n\t\tn = parser.SpaceHorizontal\n\t}\n\tif _, err = g.w.WriteStringLiteral(indentLevel, string(n)); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeDocType(indentLevel int, n *parser.DocType) (err error) {\n\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(\"<!doctype %s>\", escapeQuotes(n.Value))); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeFallthrough(indentLevel int) (err error) {\n\t_, err = g.w.WriteIndent(indentLevel, \"fallthrough\\n\")\n\treturn err\n}\n\nfunc escapeQuotes(s string) string {\n\tquoted := strconv.Quote(s)\n\treturn quoted[1 : len(quoted)-1]\n}\n\nfunc (g *generator) writeIfExpression(indentLevel int, n *parser.IfExpression, nextNode parser.Node) (err error) {\n\tvar r parser.Range\n\t// if\n\tif _, err = g.w.WriteIndent(indentLevel, `if `); err != nil {\n\t\treturn err\n\t}\n\t// x == y {\n\tif r, err = g.w.Write(n.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(n.Expression, r)\n\t// {\n\tif _, err = g.w.Write(` {` + \"\\n\"); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindentLevel++\n\t\tif err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Then), nextNode); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindentLevel--\n\t}\n\tfor _, elseIf := range n.ElseIfs {\n\t\t// } else if {\n\t\tif _, err = g.w.WriteIndent(indentLevel, `} else if `); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// x == y {\n\t\tif r, err = g.w.Write(elseIf.Expression.Value); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tg.sourceMap.Add(elseIf.Expression, r)\n\t\t// {\n\t\tif _, err = g.w.Write(` {` + \"\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t{\n\t\t\tindentLevel++\n\t\t\tif err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(elseIf.Then), nextNode); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t}\n\tif len(n.Else) > 0 {\n\t\t// } else {\n\t\tif _, err = g.w.WriteIndent(indentLevel, `} else {`+\"\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t{\n\t\t\tindentLevel++\n\t\t\tif err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Else), nextNode); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t}\n\t// }\n\tif _, err = g.w.WriteIndent(indentLevel, `}`+\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeSwitchExpression(indentLevel int, n *parser.SwitchExpression, next parser.Node) (err error) {\n\tvar r parser.Range\n\t// switch\n\tif _, err = g.w.WriteIndent(indentLevel, `switch `); err != nil {\n\t\treturn err\n\t}\n\t// val\n\tif r, err = g.w.Write(n.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(n.Expression, r)\n\t// {\n\tif _, err = g.w.Write(` {` + \"\\n\"); err != nil {\n\t\treturn err\n\t}\n\n\tif len(n.Cases) > 0 {\n\t\tfor _, c := range n.Cases {\n\t\t\t// case x:\n\t\t\t// default:\n\t\t\tif r, err = g.w.WriteIndent(indentLevel, c.Expression.Value); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tg.sourceMap.Add(c.Expression, r)\n\t\t\tindentLevel++\n\t\t\tif err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(c.Children), next); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t}\n\t// }\n\tif _, err = g.w.WriteIndent(indentLevel, `}`+\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeChildrenExpression(indentLevel int) (err error) {\n\tif _, err = g.w.WriteIndent(indentLevel, fmt.Sprintf(\"templ_7745c5c3_Err = %s.Render(ctx, templ_7745c5c3_Buffer)\\n\", g.childrenVar)); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeTemplElementExpression(indentLevel int, n *parser.TemplElementExpression) (err error) {\n\tif len(n.Children) == 0 {\n\t\treturn g.writeSelfClosingTemplElementExpression(indentLevel, n)\n\t}\n\treturn g.writeBlockTemplElementExpression(indentLevel, n)\n}\n\nfunc (g *generator) writeBlockTemplElementExpression(indentLevel int, n *parser.TemplElementExpression) (err error) {\n\tvar r parser.Range\n\tchildrenName := g.createVariableName()\n\tif _, err = g.w.WriteIndent(indentLevel, childrenName+\" := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindentLevel++\n\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err := g.writeTemplBuffer(indentLevel); err != nil {\n\t\treturn err\n\t}\n\t// ctx = templ.InitializeContext(ctx)\n\tif _, err = g.w.WriteIndent(indentLevel, \"ctx = templ.InitializeContext(ctx)\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children), nil); err != nil {\n\t\treturn err\n\t}\n\t// return nil\n\tif _, err = g.w.WriteIndent(indentLevel, \"return nil\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindentLevel--\n\tif _, err = g.w.WriteIndent(indentLevel, \"})\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif _, err = g.w.WriteIndent(indentLevel, `templ_7745c5c3_Err = `); err != nil {\n\t\treturn err\n\t}\n\tif r, err = g.w.Write(n.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(n.Expression, r)\n\t// .Render(templ.WithChildren(ctx, children), templ_7745c5c3_Buffer)\n\tif _, err = g.w.Write(\".Render(templ.WithChildren(ctx, \" + childrenName + \"), templ_7745c5c3_Buffer)\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeSelfClosingTemplElementExpression(indentLevel int, n *parser.TemplElementExpression) (err error) {\n\tif _, err = g.w.WriteIndent(indentLevel, `templ_7745c5c3_Err = `); err != nil {\n\t\treturn err\n\t}\n\t// Template expression.\n\tvar r parser.Range\n\tif r, err = g.w.Write(n.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(n.Expression, r)\n\t// .Render(ctx, templ_7745c5c3_Buffer)\n\tif _, err = g.w.Write(\".Render(ctx, templ_7745c5c3_Buffer)\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeCallTemplateExpression(indentLevel int, n *parser.CallTemplateExpression) (err error) {\n\tif _, err = g.w.WriteIndent(indentLevel, `templ_7745c5c3_Err = `); err != nil {\n\t\treturn err\n\t}\n\t// Template expression.\n\tvar r parser.Range\n\tif r, err = g.w.Write(n.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(n.Expression, r)\n\t// .Render(ctx, templ_7745c5c3_Buffer)\n\tif _, err = g.w.Write(\".Render(ctx, templ_7745c5c3_Buffer)\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeForExpression(indentLevel int, n *parser.ForExpression, next parser.Node) (err error) {\n\tvar r parser.Range\n\t// for\n\tif _, err = g.w.WriteIndent(indentLevel, `for `); err != nil {\n\t\treturn err\n\t}\n\t// i, v := range p.Stuff\n\tif r, err = g.w.Write(n.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(n.Expression, r)\n\t// {\n\tif _, err = g.w.Write(` {` + \"\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// Children.\n\tindentLevel++\n\tif err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children), next); err != nil {\n\t\treturn err\n\t}\n\tindentLevel--\n\t// }\n\tif _, err = g.w.WriteIndent(indentLevel, `}`+\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeErrorHandler(indentLevel int) (err error) {\n\t_, err = g.w.WriteIndent(indentLevel, \"if templ_7745c5c3_Err != nil {\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tindentLevel++\n\t_, err = g.w.WriteIndent(indentLevel, \"return templ_7745c5c3_Err\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tindentLevel--\n\t_, err = g.w.WriteIndent(indentLevel, \"}\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc (g *generator) writeExpressionErrorHandler(indentLevel int, expression parser.Expression) (err error) {\n\t_, err = g.w.WriteIndent(indentLevel, \"if templ_7745c5c3_Err != nil {\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tindentLevel++\n\tline := int(expression.Range.To.Line + 1)\n\tcol := int(expression.Range.To.Col)\n\t_, err = g.w.WriteIndent(indentLevel, \"return\ttempl.Error{Err: templ_7745c5c3_Err, FileName: \"+createGoString(g.options.FileName)+\", Line: \"+strconv.Itoa(line)+\", Col: \"+strconv.Itoa(col)+\"}\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tindentLevel--\n\t_, err = g.w.WriteIndent(indentLevel, \"}\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc (g *generator) writeElement(indentLevel int, n *parser.Element) (err error) {\n\tif len(n.Attributes) == 0 {\n\t\t// <div>\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(`<%s>`, html.EscapeString(n.Name))); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tattrs := parser.CopyAttributes(n.Attributes)\n\t\t// <style type=\"text/css\"></style>\n\t\tif err = g.writeElementCSS(indentLevel, attrs); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// <script></script>\n\t\tif err = g.writeElementScript(indentLevel, attrs); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// <div\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(`<%s`, html.EscapeString(n.Name))); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = g.writeElementAttributes(indentLevel, n.Name, attrs); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// >\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, `>`); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Skip children and close tag for void elements.\n\tif n.IsVoidElement() && len(n.Children) == 0 {\n\t\treturn nil\n\t}\n\t// Children.\n\tif err = g.writeNodes(indentLevel, stripWhitespace(n.Children), nil); err != nil {\n\t\treturn err\n\t}\n\t// </div>\n\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(`</%s>`, html.EscapeString(n.Name))); err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc (g *generator) writeAttributeCSS(indentLevel int, attr *parser.ExpressionAttribute) (result *parser.ExpressionAttribute, ok bool, err error) {\n\tvar r parser.Range\n\tname := html.EscapeString(attr.Key.String())\n\tif name != \"class\" {\n\t\tok = false\n\t\treturn\n\t}\n\t// Create a class name for the style.\n\t// The expression can either be expecting a templ.Classes call, or an expression that returns\n\t// var templ_7745c5c3_CSSClasses = []any{\n\tclassesName := g.createVariableName()\n\tif _, err = g.w.WriteIndent(indentLevel, \"var \"+classesName+\" = []any{\"); err != nil {\n\t\treturn\n\t}\n\t// p.Name()\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\t// }\\n\n\tif _, err = g.w.Write(\"}\\n\"); err != nil {\n\t\treturn\n\t}\n\t// Render the CSS before the element if required.\n\t// templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_CSSClasses...)\n\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, \"+classesName+\"...)\\n\"); err != nil {\n\t\treturn\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn\n\t}\n\t// Rewrite the ExpressionAttribute to point at the new variable.\n\tnewAttr := &parser.ExpressionAttribute{\n\t\tKey: attr.Key,\n\t\tExpression: parser.Expression{\n\t\t\tValue: \"templ.CSSClasses(\" + classesName + \").String()\",\n\t\t},\n\t}\n\treturn newAttr, true, nil\n}\n\nfunc (g *generator) writeAttributesCSS(indentLevel int, attrs []parser.Attribute) (err error) {\n\tfor i, attr := range attrs {\n\t\tif attr, ok := attr.(*parser.ExpressionAttribute); ok {\n\t\t\tattr, ok, err = g.writeAttributeCSS(indentLevel, attr)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif ok {\n\t\t\t\tattrs[i] = attr\n\t\t\t}\n\t\t}\n\t\tif cattr, ok := attr.(*parser.ConditionalAttribute); ok {\n\t\t\terr = g.writeAttributesCSS(indentLevel, cattr.Then)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\terr = g.writeAttributesCSS(indentLevel, cattr.Else)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tattrs[i] = cattr\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeElementCSS(indentLevel int, attrs []parser.Attribute) (err error) {\n\treturn g.writeAttributesCSS(indentLevel, attrs)\n}\n\nfunc isScriptAttribute(name string) bool {\n\tfor _, prefix := range []string{\"on\", \"hx-on:\"} {\n\t\tif strings.HasPrefix(name, prefix) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (g *generator) writeElementScript(indentLevel int, attrs []parser.Attribute) (err error) {\n\tvar scriptExpressions []string\n\tfor _, attr := range attrs {\n\t\tscriptExpressions = append(scriptExpressions, getAttributeScripts(attr)...)\n\t}\n\tif len(scriptExpressions) == 0 {\n\t\treturn\n\t}\n\t// Render the scripts before the element if required.\n\t// templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, a, b, c)\n\tif _, err = g.w.WriteIndent(indentLevel, \"templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, \"+strings.Join(scriptExpressions, \", \")+\")\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc getAttributeScripts(attr parser.Attribute) (scripts []string) {\n\tif attr, ok := attr.(*parser.ConditionalAttribute); ok {\n\t\tfor _, attr := range attr.Then {\n\t\t\tscripts = append(scripts, getAttributeScripts(attr)...)\n\t\t}\n\t\tfor _, attr := range attr.Else {\n\t\t\tscripts = append(scripts, getAttributeScripts(attr)...)\n\t\t}\n\t}\n\tif attr, ok := attr.(*parser.ExpressionAttribute); ok {\n\t\tname := html.EscapeString(attr.Key.String())\n\t\tif isScriptAttribute(name) {\n\t\t\tscripts = append(scripts, attr.Expression.Value)\n\t\t}\n\t}\n\treturn scripts\n}\n\nfunc (g *generator) writeAttributeKey(indentLevel int, attr parser.AttributeKey) (err error) {\n\tif attr, ok := attr.(parser.ConstantAttributeKey); ok {\n\t\tname := html.EscapeString(attr.Name)\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(` %s`, name)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\tif attr, ok := attr.(parser.ExpressionAttributeKey); ok {\n\t\tvar r parser.Range\n\t\tvn := g.createVariableName()\n\t\t// var vn string\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"var \"+vn+\" string\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// vn, templ_7745c5c3_Err = templ.JoinStringErrs(\n\t\tif _, err = g.w.WriteIndent(indentLevel, vn+\", templ_7745c5c3_Err = templ.JoinStringErrs(\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// p.Name()\n\t\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tg.sourceMap.Add(attr.Expression, r)\n\t\t// )\n\t\tif _, err = g.w.Write(\")\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Attribute expression error handler.\n\t\terr = g.writeExpressionErrorHandler(indentLevel, attr.Expression)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(vn)\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(` `+\"+vn+\"))\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn g.writeErrorHandler(indentLevel)\n\t}\n\treturn fmt.Errorf(\"unknown attribute key type %T\", attr)\n}\n\nfunc (g *generator) writeBoolConstantAttribute(indentLevel int, attr *parser.BoolConstantAttribute) (err error) {\n\treturn g.writeAttributeKey(indentLevel, attr.Key)\n}\n\nfunc (g *generator) writeConstantAttribute(indentLevel int, attr *parser.ConstantAttribute) (err error) {\n\tif err = g.writeAttributeKey(indentLevel, attr.Key); err != nil {\n\t\treturn err\n\t}\n\tquote := `\"`\n\tif attr.SingleQuote {\n\t\tquote = \"'\"\n\t}\n\n\t// Strip superfluous whitespace from class attributes.\n\tattrValue := attr.Value\n\tif k, ok := attr.Key.(parser.ConstantAttributeKey); ok && strings.EqualFold(k.Name, \"class\") {\n\t\tattrValue = strings.Join(strings.Fields(attrValue), \" \")\n\t}\n\n\tvalue := escapeQuotes(\"=\" + quote + attrValue + quote)\n\tif _, err = g.w.WriteStringLiteral(indentLevel, value); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeBoolExpressionAttribute(indentLevel int, attr *parser.BoolExpressionAttribute) (err error) {\n\t// if\n\tif _, err = g.w.WriteIndent(indentLevel, `if `); err != nil {\n\t\treturn err\n\t}\n\t// x == y\n\tvar r parser.Range\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\t// {\n\tif _, err = g.w.Write(` {` + \"\\n\"); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindentLevel++\n\t\tif err = g.writeAttributeKey(indentLevel, attr.Key); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindentLevel--\n\t}\n\t// }\n\tif _, err = g.w.WriteIndent(indentLevel, `}`+\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeExpressionAttributeValueURL(indentLevel int, attr *parser.ExpressionAttribute) (err error) {\n\tvn := g.createVariableName()\n\t// var vn templ.SafeURL\n\tif _, err = g.w.WriteIndent(indentLevel, \"var \"+vn+\" templ.SafeURL\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// vn, templ_7745c5c3_Err = templ.JoinURLErrs(\n\tif _, err = g.w.WriteIndent(indentLevel, vn+\", templ_7745c5c3_Err = templ.JoinURLErrs(\"); err != nil {\n\t\treturn err\n\t}\n\t// p.Name()\n\tvar r parser.Range\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\t// )\n\tif _, err = g.w.Write(\")\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// Attribute expression error handler.\n\terr = g.writeExpressionErrorHandler(indentLevel, attr.Expression)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(vn)\n\tif _, err = g.w.WriteIndent(indentLevel, \"_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(\"+vn+\"))\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn g.writeErrorHandler(indentLevel)\n}\n\nfunc (g *generator) writeExpressionAttributeValueScript(indentLevel int, attr *parser.ExpressionAttribute) (err error) {\n\t// It's a JavaScript handler, and requires special handling, because we expect a JavaScript expression.\n\tvn := g.createVariableName()\n\t// var vn templ.ComponentScript =\n\tif _, err = g.w.WriteIndent(indentLevel, \"var \"+vn+\" templ.ComponentScript = \"); err != nil {\n\t\treturn err\n\t}\n\t// p.Name()\n\tvar r parser.Range\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\tif _, err = g.w.Write(\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif _, err = g.w.WriteIndent(indentLevel, \"_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(\"+vn+\".Call)\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn g.writeErrorHandler(indentLevel)\n}\n\nfunc (g *generator) writeExpressionAttributeValueDefault(indentLevel int, attr *parser.ExpressionAttribute) (err error) {\n\tvar r parser.Range\n\tvn := g.createVariableName()\n\t// var vn string\n\tif _, err = g.w.WriteIndent(indentLevel, \"var \"+vn+\" string\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// vn, templ_7745c5c3_Err = templ.JoinStringErrs(\n\tif _, err = g.w.WriteIndent(indentLevel, vn+\", templ_7745c5c3_Err = templ.JoinStringErrs(\"); err != nil {\n\t\treturn err\n\t}\n\t// p.Name()\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\t// )\n\tif _, err = g.w.Write(\")\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// Attribute expression error handler.\n\terr = g.writeExpressionErrorHandler(indentLevel, attr.Expression)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(vn)\n\tif _, err = g.w.WriteIndent(indentLevel, \"_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(\"+vn+\"))\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn g.writeErrorHandler(indentLevel)\n}\n\nfunc (g *generator) writeExpressionAttributeValueStyle(indentLevel int, attr *parser.ExpressionAttribute) (err error) {\n\tvar r parser.Range\n\tvn := g.createVariableName()\n\t// var vn string\n\tif _, err = g.w.WriteIndent(indentLevel, \"var \"+vn+\" string\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// vn, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues(\n\tif _, err = g.w.WriteIndent(indentLevel, vn+\", templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues(\"); err != nil {\n\t\treturn err\n\t}\n\t// value\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\t// )\n\tif _, err = g.w.Write(\")\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// Attribute expression error handler.\n\terr = g.writeExpressionErrorHandler(indentLevel, attr.Expression)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(vn))\n\tif _, err = g.w.WriteIndent(indentLevel, \"_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(\"+vn+\"))\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn g.writeErrorHandler(indentLevel)\n}\n\nfunc (g *generator) writeExpressionAttribute(indentLevel int, elementName string, attr *parser.ExpressionAttribute) (err error) {\n\tif err = g.writeAttributeKey(indentLevel, attr.Key); err != nil {\n\t\treturn err\n\t}\n\t// =\"\n\tif _, err = g.w.WriteStringLiteral(indentLevel, `=\\\"`); err != nil {\n\t\treturn err\n\t}\n\tattrKey := html.EscapeString(attr.Key.String())\n\t// Value.\n\tif isExpressionAttributeValueURL(elementName, attrKey) {\n\t\tif err := g.writeExpressionAttributeValueURL(indentLevel, attr); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if isScriptAttribute(attrKey) {\n\t\tif err := g.writeExpressionAttributeValueScript(indentLevel, attr); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if attrKey == \"style\" {\n\t\tif err := g.writeExpressionAttributeValueStyle(indentLevel, attr); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif err := g.writeExpressionAttributeValueDefault(indentLevel, attr); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Close quote.\n\tif _, err = g.w.WriteStringLiteral(indentLevel, `\\\"`); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeSpreadAttributes(indentLevel int, attr *parser.SpreadAttributes) (err error) {\n\t// templ.RenderAttributes(ctx, w, spreadAttrs)\n\tif _, err = g.w.WriteIndent(indentLevel, `templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, `); err != nil {\n\t\treturn err\n\t}\n\t// spreadAttrs\n\tvar r parser.Range\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\t// )\n\tif _, err = g.w.Write(\")\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeConditionalAttribute(indentLevel int, elementName string, attr *parser.ConditionalAttribute) (err error) {\n\t// if\n\tif _, err = g.w.WriteIndent(indentLevel, `if `); err != nil {\n\t\treturn err\n\t}\n\t// x == y\n\tvar r parser.Range\n\tif r, err = g.w.Write(attr.Expression.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(attr.Expression, r)\n\t// {\n\tif _, err = g.w.Write(` {` + \"\\n\"); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindentLevel++\n\t\tif err = g.writeElementAttributes(indentLevel, elementName, attr.Then); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindentLevel--\n\t}\n\tif len(attr.Else) > 0 {\n\t\t// } else {\n\t\tif _, err = g.w.WriteIndent(indentLevel, `} else {`+\"\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t{\n\t\t\tindentLevel++\n\t\t\tif err = g.writeElementAttributes(indentLevel, elementName, attr.Else); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tindentLevel--\n\t\t}\n\t}\n\t// }\n\tif _, err = g.w.WriteIndent(indentLevel, `}`+\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeElementAttributes(indentLevel int, name string, attrs []parser.Attribute) (err error) {\n\tfor _, attr := range attrs {\n\t\tswitch attr := attr.(type) {\n\t\tcase *parser.BoolConstantAttribute:\n\t\t\terr = g.writeBoolConstantAttribute(indentLevel, attr)\n\t\tcase *parser.ConstantAttribute:\n\t\t\terr = g.writeConstantAttribute(indentLevel, attr)\n\t\tcase *parser.BoolExpressionAttribute:\n\t\t\terr = g.writeBoolExpressionAttribute(indentLevel, attr)\n\t\tcase *parser.ExpressionAttribute:\n\t\t\terr = g.writeExpressionAttribute(indentLevel, name, attr)\n\t\tcase *parser.SpreadAttributes:\n\t\t\terr = g.writeSpreadAttributes(indentLevel, attr)\n\t\tcase *parser.ConditionalAttribute:\n\t\t\terr = g.writeConditionalAttribute(indentLevel, name, attr)\n\t\tdefault:\n\t\t\terr = fmt.Errorf(\"unknown attribute type %T\", attr)\n\t\t}\n\t}\n\treturn\n}\n\nfunc (g *generator) writeRawElement(indentLevel int, n *parser.RawElement) (err error) {\n\tif len(n.Attributes) == 0 {\n\t\t// <div>\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(`<%s>`, html.EscapeString(n.Name))); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// <script></script>\n\t\tif err = g.writeElementScript(indentLevel, n.Attributes); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// <div\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(`<%s`, html.EscapeString(n.Name))); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = g.writeElementAttributes(indentLevel, n.Name, n.Attributes); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// >\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, `>`); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Contents.\n\tif err = g.writeText(indentLevel, &parser.Text{Value: n.Contents}); err != nil {\n\t\treturn err\n\t}\n\t// </div>\n\tif _, err = g.w.WriteStringLiteral(indentLevel, fmt.Sprintf(`</%s>`, html.EscapeString(n.Name))); err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc (g *generator) writeScriptElement(indentLevel int, n *parser.ScriptElement) (err error) {\n\tif len(n.Attributes) == 0 {\n\t\t// <div>\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, `<script>`); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// <script></script>\n\t\tif err = g.writeElementScript(indentLevel, n.Attributes); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// <div\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, \"<script\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = g.writeElementAttributes(indentLevel, \"script\", n.Attributes); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// >\n\t\tif _, err = g.w.WriteStringLiteral(indentLevel, `>`); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Contents.\n\tfor _, c := range n.Contents {\n\t\tif err = g.writeScriptContents(indentLevel, c); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// </div>\n\tif _, err = g.w.WriteStringLiteral(indentLevel, \"</script>\"); err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc (g *generator) writeScriptContents(indentLevel int, c parser.ScriptContents) (err error) {\n\tif c.Value != nil {\n\t\tif *c.Value == \"\" {\n\t\t\treturn nil\n\t\t}\n\t\t// This is a JS expression and can be written directly to the output.\n\t\treturn g.writeText(indentLevel, &parser.Text{Value: *c.Value})\n\t}\n\tif c.GoCode != nil {\n\t\t// This is a Go code block. The code needs to be evaluated, and the result written to the output.\n\t\t// The variable is JSON encoded to ensure that it is safe to use within a script tag.\n\t\tvar r parser.Range\n\t\tvn := g.createVariableName()\n\t\t// Here, we need to get the result, which might be any type. We can use templ.ScriptContent to get the result.\n\t\t// vn, templ_7745c5c3_Err := templruntime.ScriptContent(\n\t\tfnCall := \"templruntime.ScriptContentOutsideStringLiteral\"\n\t\tif c.InsideStringLiteral {\n\t\t\tfnCall = \"templruntime.ScriptContentInsideStringLiteral\"\n\t\t}\n\t\tif _, err = g.w.WriteIndent(indentLevel, vn+\", templ_7745c5c3_Err := \"+fnCall+\"(\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// p.Name()\n\t\tif r, err = g.w.Write(c.GoCode.Expression.Value); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tg.sourceMap.Add(c.GoCode.Expression, r)\n\t\t// )\n\t\tif _, err = g.w.Write(\")\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Expression error handler.\n\t\terr = g.writeExpressionErrorHandler(indentLevel, c.GoCode.Expression)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(jvn)\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(\"+vn+\")\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Write any trailing space.\n\t\tif c.GoCode.TrailingSpace != \"\" {\n\t\t\tif err = g.writeText(indentLevel, &parser.Text{Value: string(c.GoCode.TrailingSpace)}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\treturn nil\n\t}\n\treturn errors.New(\"unknown script content\")\n}\n\nfunc (g *generator) writeComment(indentLevel int, c *parser.HTMLComment) (err error) {\n\t// <!--\n\tif _, err = g.w.WriteStringLiteral(indentLevel, \"<!--\"); err != nil {\n\t\treturn err\n\t}\n\t// Contents.\n\tif err = g.writeText(indentLevel, &parser.Text{Value: c.Contents}); err != nil {\n\t\treturn err\n\t}\n\t// -->\n\tif _, err = g.w.WriteStringLiteral(indentLevel, \"-->\"); err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc (g *generator) createVariableName() string {\n\tg.variableID++\n\treturn \"templ_7745c5c3_Var\" + strconv.Itoa(g.variableID)\n}\n\nfunc (g *generator) writeGoCode(indentLevel int, e parser.Expression) (err error) {\n\tif strings.TrimSpace(e.Value) == \"\" {\n\t\treturn\n\t}\n\tvar r parser.Range\n\tif r, err = g.w.WriteIndent(indentLevel, e.Value+\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(e, r)\n\treturn nil\n}\n\nfunc (g *generator) writeStringExpression(indentLevel int, e parser.Expression) (err error) {\n\tif strings.TrimSpace(e.Value) == \"\" {\n\t\treturn\n\t}\n\tvar r parser.Range\n\tvn := g.createVariableName()\n\t// var vn string\n\tif _, err = g.w.WriteIndent(indentLevel, \"var \"+vn+\" string\\n\"); err != nil {\n\t\treturn err\n\t}\n\t// vn, templ_7745c5c3_Err = templ.JoinStringErrs(\n\tif _, err = g.w.WriteIndent(indentLevel, vn+\", templ_7745c5c3_Err = templ.JoinStringErrs(\"); err != nil {\n\t\treturn err\n\t}\n\t// p.Name()\n\tif r, err = g.w.Write(e.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(e, r)\n\t// )\n\tif _, err = g.w.Write(\")\\n\"); err != nil {\n\t\treturn err\n\t}\n\n\t// String expression error handler.\n\terr = g.writeExpressionErrorHandler(indentLevel, e)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(vn)\n\tif _, err = g.w.WriteIndent(indentLevel, \"_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(\"+vn+\"))\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err = g.writeErrorHandler(indentLevel); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeWhitespace(indentLevel int, n *parser.Whitespace) (err error) {\n\tif len(n.Value) == 0 {\n\t\treturn\n\t}\n\t// _, err = templ_7745c5c3_Buffer.WriteString(` `)\n\tif _, err = g.w.WriteStringLiteral(indentLevel, \" \"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (g *generator) writeText(indentLevel int, n *parser.Text) (err error) {\n\t_, err = g.w.WriteStringLiteral(indentLevel, escapeQuotes(n.Value))\n\treturn err\n}\n\nfunc createGoString(s string) string {\n\tvar sb strings.Builder\n\tsb.WriteRune('`')\n\tsects := strings.Split(s, \"`\")\n\tfor i, sect := range sects {\n\t\tsb.WriteString(sect)\n\t\tif len(sects) > i+1 {\n\t\t\tsb.WriteString(\"` + \\\"`\\\" + `\")\n\t\t}\n\t}\n\tsb.WriteRune('`')\n\treturn sb.String()\n}\n\nfunc (g *generator) writeScript(t *parser.ScriptTemplate) error {\n\tif t == nil {\n\t\treturn errors.New(\"script template is nil\")\n\t}\n\tvar r parser.Range\n\tvar tgtSymbolRange parser.Range\n\tvar err error\n\tvar indentLevel int\n\n\t// func\n\tif r, err = g.w.Write(\"func \"); err != nil {\n\t\treturn err\n\t}\n\ttgtSymbolRange.From = r.From\n\tif r, err = g.w.Write(t.Name.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(t.Name, r)\n\t// (\n\tif _, err = g.w.Write(\"(\"); err != nil {\n\t\treturn err\n\t}\n\t// Write parameters.\n\tif r, err = g.w.Write(t.Parameters.Value); err != nil {\n\t\treturn err\n\t}\n\tg.sourceMap.Add(t.Parameters, r)\n\t// ) templ.ComponentScript {\n\tif _, err = g.w.Write(\") templ.ComponentScript {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindentLevel++\n\t// return templ.ComponentScript{\n\tif _, err = g.w.WriteIndent(indentLevel, \"return templ.ComponentScript{\\n\"); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindentLevel++\n\t\tfn := functionName(t.Name.Value, t.Value)\n\t\tgoFn := createGoString(fn)\n\t\t// Name: \"scriptName\",\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"Name: \"+goFn+\",\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Function: `function scriptName(a, b, c){` + `constantScriptValue` + `}`,\n\t\tprefix := \"function \" + fn + \"(\" + stripTypes(t.Parameters.Value) + \"){\"\n\t\tbody := strings.TrimLeftFunc(t.Value, unicode.IsSpace)\n\t\tsuffix := \"}\"\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"Function: \"+createGoString(prefix+body+suffix)+\",\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Call: templ.SafeScript(scriptName, a, b, c)\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"Call: templ.SafeScript(\"+goFn+\", \"+stripTypes(t.Parameters.Value)+\"),\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// CallInline: templ.SafeScriptInline(scriptName, a, b, c)\n\t\tif _, err = g.w.WriteIndent(indentLevel, \"CallInline: templ.SafeScriptInline(\"+goFn+\", \"+stripTypes(t.Parameters.Value)+\"),\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindentLevel--\n\t}\n\t// }\n\tif _, err = g.w.WriteIndent(indentLevel, \"}\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindentLevel--\n\t// }\n\tif r, err = g.w.WriteIndent(indentLevel, \"}\\n\\n\"); err != nil {\n\t\treturn err\n\t}\n\n\t// Keep track of the symbol range for the LSP.\n\ttgtSymbolRange.To = r.To\n\tg.sourceMap.AddSymbolRange(t.Range, tgtSymbolRange)\n\n\treturn nil\n}\n\n// writeBlankAssignmentForRuntimeImport writes out a blank identifier assignment.\n// This ensures that even if the github.com/a-h/templ/runtime package is not used in the generated code,\n// the Go compiler will not complain about the unused import.\nfunc (g *generator) writeBlankAssignmentForRuntimeImport() error {\n\tvar err error\n\tif _, err = g.w.Write(\"var _ = templruntime.GeneratedTemplate\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc functionName(name string, body string) string {\n\th := sha256.New()\n\th.Write([]byte(body))\n\thp := hex.EncodeToString(h.Sum(nil))[0:4]\n\treturn \"__templ_\" + name + \"_\" + hp\n}\n\nfunc stripTypes(parameters string) string {\n\tvariableNames := []string{}\n\tparams := strings.Split(parameters, \",\")\n\tfor _, param := range params {\n\t\tp := strings.Split(strings.TrimSpace(param), \" \")\n\t\tvariableNames = append(variableNames, strings.TrimSpace(p[0]))\n\t}\n\treturn strings.Join(variableNames, \", \")\n}\n\nfunc isExpressionAttributeValueURL(elementName, attrName string) bool {\n\tswitch elementName {\n\tcase \"a\", \"link\":\n\t\treturn attrName == \"href\"\n\tcase \"form\":\n\t\treturn attrName == \"action\"\n\tcase \"object\":\n\t\treturn attrName == \"data\"\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "generator/generator_test.go",
    "content": "package generator\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestGeneratorSourceMap(t *testing.T) {\n\tw := new(bytes.Buffer)\n\tg := generator{\n\t\tw:         NewRangeWriter(w),\n\t\tsourceMap: parser.NewSourceMap(),\n\t}\n\tinvalidExp := &parser.TemplateFileGoExpression{\n\t\tExpression: parser.Expression{\n\t\t\tValue: \"line1\\nline2\",\n\t\t},\n\t}\n\tif err := g.writeGoExpression(invalidExp); err != nil {\n\t\tt.Fatalf(\"failed to write Go expression: %v\", err)\n\t}\n\n\texpected := parser.NewPosition(0, 0, 0)\n\tactual, ok := g.sourceMap.TargetPositionFromSource(0, 0)\n\tif !ok {\n\t\tt.Errorf(\"failed to get matching target\")\n\t}\n\tif diff := cmp.Diff(expected, actual); diff != \"\" {\n\t\tt.Errorf(\"unexpected target:\\n%v\", diff)\n\t}\n\n\twithCommentExp := &parser.TemplateFileGoExpression{\n\t\tExpression: parser.Expression{\n\t\t\tValue: `package main\n\n// A comment.\ntempl h1() {\n\t<h1></h1>\n}\n\t\t\t`,\n\t\t},\n\t}\n\tif err := g.writeGoExpression(withCommentExp); err != nil {\n\t\tt.Fatalf(\"failed to write Go expression: %v\", err)\n\t}\n}\n\nfunc TestGeneratorForLSP(t *testing.T) {\n\tinput := `package main\n\ntempl Hello(name string) {\n  if nam`\n\ttf, err := parser.ParseString(input)\n\tif err == nil {\n\t\tt.Fatalf(\"expected error, because the file is not valid, got nil\")\n\t}\n\n\tw := new(bytes.Buffer)\n\top, err := Generate(tf, w)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to generate: %v\", err)\n\t}\n\tif op.SourceMap == nil {\n\t\tt.Fatal(\"expected source map for if expression, got nil\")\n\t}\n\tif len(op.SourceMap.Expressions) != 3 {\n\t\tt.Errorf(\"expected an expression for the package name, template signature (Hello) and for the if (nam), got %#v\", op.SourceMap.Expressions)\n\t}\n}\n\nfunc TestIsExpressionAttributeValueURL(t *testing.T) {\n\ttestCases := []struct {\n\t\telementName    string\n\t\tattrName       string\n\t\texpectedOutput bool\n\t}{\n\t\t{\n\t\t\telementName:    \"a\",\n\t\t\tattrName:       \"href\",\n\t\t\texpectedOutput: true,\n\t\t},\n\t\t{\n\t\t\telementName:    \"a\",\n\t\t\tattrName:       \"class\",\n\t\t\texpectedOutput: false,\n\t\t},\n\t\t{\n\t\t\telementName:    \"div\",\n\t\t\tattrName:       \"class\",\n\t\t\texpectedOutput: false,\n\t\t},\n\t\t{\n\t\t\telementName:    \"p\",\n\t\t\tattrName:       \"href\",\n\t\t\texpectedOutput: false,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tif output := isExpressionAttributeValueURL(testCase.elementName, testCase.attrName); output != testCase.expectedOutput {\n\t\t\tt.Errorf(\"expected %t got %t\", testCase.expectedOutput, output)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "generator/htmldiff/diff.go",
    "content": "package htmldiff\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/internal/prettier\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\nfunc DiffStrings(expected, actual string) (output, diff string, err error) {\n\t// Format both strings.\n\tvar wg errgroup.Group\n\n\t// Format expected.\n\twg.Go(func() (err error) {\n\t\texpected, err = prettier.Run(expected, \"expected.html\", prettier.DefaultCommand())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\n\t// Format actual.\n\twg.Go(func() (err error) {\n\t\tactual, err = prettier.Run(actual, \"actual.html\", prettier.DefaultCommand())\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"actual html formatting error: %w\", err)\n\t\t}\n\t\treturn nil\n\t})\n\n\t// Wait for processing.\n\tif err = wg.Wait(); err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\treturn actual, cmp.Diff(expected, actual), nil\n}\n\nfunc Diff(input templ.Component, expected string) (actual, diff string, err error) {\n\treturn DiffCtx(context.Background(), input, expected)\n}\n\nfunc DiffCtx(ctx context.Context, input templ.Component, expected string) (actual, diff string, err error) {\n\tvar a strings.Builder\n\terr = input.Render(ctx, &a)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to render input: %w\", err)\n\t}\n\treturn DiffStrings(expected, a.String())\n}\n"
  },
  {
    "path": "generator/rangewriter.go",
    "content": "package generator\n\nimport (\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\nfunc NewRangeWriter(w io.Writer) *RangeWriter {\n\treturn &RangeWriter{\n\t\tw:       w,\n\t\tbuilder: &strings.Builder{},\n\t}\n}\n\ntype RangeWriter struct {\n\tCurrent   parser.Position\n\tinLiteral bool\n\tw         io.Writer\n\n\t// Extract strings.\n\tindex    int\n\tbuilder  *strings.Builder\n\tLiterals []string\n}\n\nfunc (rw *RangeWriter) closeLiteral(indent int) (r parser.Range, err error) {\n\trw.inLiteral = false\n\trw.index++\n\n\tvar sb strings.Builder\n\tsb.WriteString(strings.Repeat(\"\\t\", indent))\n\tsb.WriteString(`templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, `)\n\tsb.WriteString(strconv.Itoa(rw.index))\n\tsb.WriteString(`, \"`)\n\tliteral := rw.builder.String()\n\trw.Literals = append(rw.Literals, literal)\n\tsb.WriteString(literal)\n\trw.builder.Reset()\n\tsb.WriteString(`\")`)\n\tsb.WriteString(\"\\n\")\n\n\tif _, err := rw.write(sb.String()); err != nil {\n\t\treturn r, err\n\t}\n\n\terr = rw.writeErrorHandler(indent)\n\treturn\n}\n\nfunc (rw *RangeWriter) WriteIndent(level int, s string) (r parser.Range, err error) {\n\tif rw.inLiteral {\n\t\tif _, err = rw.closeLiteral(level); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\t_, err = rw.write(strings.Repeat(\"\\t\", level))\n\tif err != nil {\n\t\treturn\n\t}\n\treturn rw.write(s)\n}\n\nfunc (rw *RangeWriter) WriteStringLiteral(level int, s string) (r parser.Range, err error) {\n\trw.inLiteral = true\n\trw.builder.WriteString(s)\n\treturn\n}\n\nfunc (rw *RangeWriter) Write(s string) (r parser.Range, err error) {\n\tif rw.inLiteral {\n\t\tif _, err = rw.closeLiteral(0); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn rw.write(s)\n}\n\nfunc (rw *RangeWriter) write(s string) (r parser.Range, err error) {\n\tr.From = parser.Position{\n\t\tIndex: rw.Current.Index,\n\t\tLine:  rw.Current.Line,\n\t\tCol:   rw.Current.Col,\n\t}\n\tutf8Bytes := make([]byte, 4)\n\tfor _, c := range s {\n\t\trlen := utf8.EncodeRune(utf8Bytes, c)\n\t\trw.Current.Col += uint32(rlen)\n\t\tif c == '\\n' {\n\t\t\trw.Current.Line++\n\t\t\trw.Current.Col = 0\n\t\t}\n\t\t_, err = rw.w.Write(utf8Bytes[:rlen])\n\t\trw.Current.Index += int64(rlen)\n\t\tif err != nil {\n\t\t\treturn r, err\n\t\t}\n\t}\n\tr.To = rw.Current\n\treturn r, err\n}\n\nfunc (rw *RangeWriter) writeErrorHandler(indentLevel int) (err error) {\n\t_, err = rw.WriteIndent(indentLevel, \"if templ_7745c5c3_Err != nil {\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tindentLevel++\n\t_, err = rw.WriteIndent(indentLevel, \"return templ_7745c5c3_Err\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tindentLevel--\n\t_, err = rw.WriteIndent(indentLevel, \"}\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "generator/rangewriter_test.go",
    "content": "package generator\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestRangeWriter(t *testing.T) {\n\tw := new(bytes.Buffer)\n\trw := NewRangeWriter(w)\n\tt.Run(\"indices are zero bound\", func(t *testing.T) {\n\t\tif diff := cmp.Diff(parser.NewPosition(0, 0, 0), rw.Current); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"writing characters increases the col position\", func(t *testing.T) {\n\t\tif _, err := rw.Write(\"abc\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(parser.NewPosition(3, 0, 3), rw.Current); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"newline characters implement carriage return\", func(t *testing.T) {\n\t\tif _, err := rw.Write(\"\\n1\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(parser.NewPosition(5, 1, 1), rw.Current); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"multi-byte characters count as 3, because that's their UTF8 representation\", func(t *testing.T) {\n\t\tif _, err := rw.Write(\"\\n你\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(parser.NewPosition(9, 2, 3), rw.Current); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"a range is returned from each write\", func(t *testing.T) {\n\t\tif _, err := rw.Write(\"\\n\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write: %v\", err)\n\t\t}\n\t\tr, err := rw.Write(\"test\")\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"expected successful write, got error: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(parser.NewPosition(10, 3, 0), r.From); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected from:\\n%s\", diff)\n\t\t}\n\t\tif diff := cmp.Diff(parser.NewPosition(14, 3, 4), r.To); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected to:\\n%s\", diff)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "generator/test-a-href/expected.html",
    "content": "<a href=\"javascript:alert('unaffected');\">Ignored</a>\n<a href=\"about:invalid#TemplFailedSanitizationURL\">Sanitized</a>\n<a href=\"javascript:alert(&#39;should not be sanitized&#39;)\">Unsanitized</a>\n"
  },
  {
    "path": "generator/test-a-href/render_test.go",
    "content": "package testahref\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-a-href/template.templ",
    "content": "package testahref\n\ntempl render() {\n\t<a href=\"javascript:alert('unaffected');\">Ignored</a>\n\t<a href={ templ.URL(\"javascript:alert('should be sanitized')\") }>Sanitized</a>\n\t<a href={ templ.SafeURL(\"javascript:alert('should not be sanitized')\") }>Unsanitized</a>\n}\n"
  },
  {
    "path": "generator/test-a-href/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testahref\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<a href=\\\"javascript:alert('unaffected');\\\">Ignored</a> <a href=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.SafeURL\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(\"javascript:alert('should be sanitized')\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-a-href/template.templ`, Line: 5, Col: 63}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">Sanitized</a> <a href=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 templ.SafeURL\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(\"javascript:alert('should not be sanitized')\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-a-href/template.templ`, Line: 6, Col: 71}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\">Unsanitized</a>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-attribute-errors/expected.html",
    "content": "<ul>\n\t<li data-attr=\"raw\"></li>\n\t<li data-attr=\"OK\"></li>\n\t<li data-attr=\"OK2\"></li>\n</ul>\n"
  },
  {
    "path": "generator/test-attribute-errors/render_test.go",
    "content": "package testattrerrs\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t_ \"embed\"\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tt.Parallel()\n\tt.Run(\"can render without error\", func(t *testing.T) {\n\t\tcomponent := TestComponent(nil)\n\n\t\t_, _, err := htmldiff.Diff(component, expected)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"attribute expressions can return errors\", func(t *testing.T) {\n\t\terrSomethingBad := errors.New(\"bad error\")\n\n\t\terr := TestComponent(errSomethingBad).Render(context.Background(), &bytes.Buffer{})\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"expected error, but got nil\")\n\t\t}\n\n\t\tt.Run(\"the errors are templ errors\", func(t *testing.T) {\n\t\t\tvar templateErr templ.Error\n\t\t\tif !errors.As(err, &templateErr) {\n\t\t\t\tt.Fatalf(\"expected error to be templ.Error, but got %T\", err)\n\t\t\t}\n\t\t\tif templateErr.FileName != `generator/test-attribute-errors/template.templ` {\n\t\t\t\tt.Errorf(\"expected error in `generator/test-attribute-errors/template.templ`, but got %v\", templateErr.FileName)\n\t\t\t}\n\t\t\tif templateErr.Line != 18 {\n\t\t\t\tt.Errorf(\"expected error on line 18, but got %v\", templateErr.Line)\n\t\t\t}\n\t\t\tif templateErr.Col != 36 {\n\t\t\t\tt.Errorf(\"expected error on column 26, but got %v\", templateErr.Col)\n\t\t\t}\n\t\t})\n\n\t\tt.Run(\"the underlying error can be unwrapped\", func(t *testing.T) {\n\t\t\tif !errors.Is(err, errSomethingBad) {\n\t\t\t\tt.Errorf(\"expected error: %v, but got %v\", errSomethingBad, err)\n\t\t\t}\n\t\t})\n\n\t})\n}\n"
  },
  {
    "path": "generator/test-attribute-errors/template.templ",
    "content": "package testattrerrs\n\nfunc funcWithNoError() (s string) {\n\treturn \"OK\"\n}\n\nfunc funcWithError(in error) (s string, err error) {\n\tif in != nil {\n\t\treturn \"\", in\n\t}\n\treturn \"OK2\", nil\n}\n\ntempl TestComponent(err error) {\n\t<ul>\n\t\t<li data-attr={ \"raw\" }></li>\n\t\t<li data-attr={ funcWithNoError() }></li>\n\t\t<li data-attr={ funcWithError(err) }></li>\n\t</ul>\n}\n"
  },
  {
    "path": "generator/test-attribute-errors/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testattrerrs\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc funcWithNoError() (s string) {\n\treturn \"OK\"\n}\n\nfunc funcWithError(in error) (s string, err error) {\n\tif in != nil {\n\t\treturn \"\", in\n\t}\n\treturn \"OK2\", nil\n}\n\nfunc TestComponent(err error) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<ul><li data-attr=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(\"raw\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-attribute-errors/template.templ`, Line: 16, Col: 23}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\"></li><li data-attr=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(funcWithNoError())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-attribute-errors/template.templ`, Line: 17, Col: 35}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\"></li><li data-attr=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(funcWithError(err))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-attribute-errors/template.templ`, Line: 18, Col: 36}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\"></li></ul>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-attribute-escaping/expected.html",
    "content": "<div><a href=\"about:invalid#TemplFailedSanitizationURL\">text</a></div>\n<div>\n  <button hx-post=\"/click\" hx-trigger=\"click\" hx-vals='{\"val\":\"Value\"}'>\n    Click\n  </button>\n</div>\n"
  },
  {
    "path": "generator/test-attribute-escaping/render_test.go",
    "content": "package testhtml\n\nimport (\n\t_ \"embed\"\n\t\"testing\"\n\n\t\"os\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tt.Parallel()\n\tcomponent := BasicTemplate(`javascript: alert(\"xss\");`)\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-attribute-escaping/template.templ",
    "content": "package testhtml\n\ntempl BasicTemplate(url string) {\n\t<div>\n\t\t<a href={ templ.URL(url) }>text</a>\n\t</div>\n\t<div>\n\t\t<button\n\t\t\thx-post=\"/click\"\n\t\t\thx-trigger=\"click\"\n\t\t\thx-vals='{\"val\":\"Value\"}'\n\t\t>Click</button>\n\t</div>\n}\n"
  },
  {
    "path": "generator/test-attribute-escaping/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testhtml\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc BasicTemplate(url string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div><a href=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.SafeURL\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(url))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-attribute-escaping/template.templ`, Line: 5, Col: 26}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">text</a></div><div><button hx-post=\\\"/click\\\" hx-trigger=\\\"click\\\" hx-vals='{\\\"val\\\":\\\"Value\\\"}'>Click</button></div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-call/expected.html",
    "content": "<div>A</div>\n<div>B</div>\n<div>C</div>\n<div>Legacy call style</div>\n<div>e</div>\n<div id=\"wrapper\"><div>Child content</div></div>\n"
  },
  {
    "path": "generator/test-call/render_test.go",
    "content": "package testcall\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := showAll()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-call/template.templ",
    "content": "package testcall\n\ntempl showAll() {\n\t@a()\n\t@b(c(\"C\"))\n\t@d()\n\t@showOne(e())\n\t@wrapChildren() {\n\t\t<div>Child content</div>\n\t}\n}\n\ntempl a() {\n\t<div>A</div>\n}\n\ntempl b(child templ.Component) {\n\t<div>B</div>\n\t@child\n}\n\ntempl c(text string) {\n\t<div>{ text }</div>\n}\n\ntempl d() {\n\t<div>Legacy call style</div>\n}\n\ntempl e() {\n\te\n}\n\ntempl showOne(component templ.Component) {\n\t<div>\n\t\t@component\n\t</div>\n}\n\ntempl wrapChildren() {\n\t<div id=\"wrapper\">\n\t\t{ children... }\n\t</div>\n}\n"
  },
  {
    "path": "generator/test-call/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcall\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc showAll() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = a().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = b(c(\"C\")).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = d().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = showOne(e()).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Child content</div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = wrapChildren().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc a() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<div>A</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc b(child templ.Component) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<div>B</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = child.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc c(text string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 string\n\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(text)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-call/template.templ`, Line: 23, Col: 12}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc d() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var7 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var7 == nil {\n\t\t\ttempl_7745c5c3_Var7 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<div>Legacy call style</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc e() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var8 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var8 == nil {\n\t\t\ttempl_7745c5c3_Var8 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"e\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc showOne(component templ.Component) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var9 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var9 == nil {\n\t\t\ttempl_7745c5c3_Var9 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = component.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc wrapChildren() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var10 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var10 == nil {\n\t\t\ttempl_7745c5c3_Var10 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"<div id=\\\"wrapper\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ_7745c5c3_Var10.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-cancelled-context/render_test.go",
    "content": "package testcancelledcontext\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n)\n\nfunc Test(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tcancel()\n\terr := EmptyComponent().Render(ctx, io.Discard)\n\tif err != context.Canceled {\n\t\tt.Errorf(\"expected deadline exceeded, got %v (%T)\", err, err)\n\t}\n}\n"
  },
  {
    "path": "generator/test-cancelled-context/template.templ",
    "content": "package testcancelledcontext\n\ntempl EmptyComponent() {\n}\n"
  },
  {
    "path": "generator/test-cancelled-context/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcancelledcontext\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc EmptyComponent() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-class-whitespace/expected.html",
    "content": "<div class=\"flex w-full h-full justify-center items-center hover:bg-blue-50\">Multiline class attribute</div>\n<div class=\"a b c\">Extra spaces between classes</div>\n<div class=\"a b c\">Leading and trailing spaces</div>\n<div class=\"a b c\">Tabs and newlines</div>\n<div class=\"a b c\">Uppercase CLASS attribute</div>\n<div data-class=\"a  b  c\">Non-class attributes unchanged</div>"
  },
  {
    "path": "generator/test-class-whitespace/render_test.go",
    "content": "package testclasswhitespace\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := TestComponent()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-class-whitespace/template.templ",
    "content": "package testclasswhitespace\n\n// Test that whitespace is stripped from class attributes.\ntempl MultilineClassAttribute() {\n\t<div\n\t\tclass=\"\n\t\t\tflex w-full h-full\n\t\t\tjustify-center items-center\n\t\t\thover:bg-blue-50\n\t\t\"\n\t>Multiline class attribute</div>\n}\n\ntempl ExtraSpaces() {\n\t<div class=\"a    b    c\">Extra spaces between classes</div>\n}\n\ntempl LeadingTrailingSpaces() {\n\t<div class=\"   a b c   \">Leading and trailing spaces</div>\n}\n\ntempl TabsAndNewlines() {\n\t<div\n\t\tclass=\"a\n\tb\n\n\tc\"\n\t>Tabs and newlines</div>\n}\n\ntempl CaseInsensitive() {\n\t<div CLASS=\"a  b  c\">Uppercase CLASS attribute</div>\n}\n\ntempl OtherAttributesUnchanged() {\n\t<div data-class=\"a  b  c\">Non-class attributes unchanged</div>\n}\n\ntempl TestComponent() {\n\t@MultilineClassAttribute()\n\t@ExtraSpaces()\n\t@LeadingTrailingSpaces()\n\t@TabsAndNewlines()\n\t@CaseInsensitive()\n\t@OtherAttributesUnchanged()\n}\n"
  },
  {
    "path": "generator/test-class-whitespace/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testclasswhitespace\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\n// Test that whitespace is stripped from class attributes.\nfunc MultilineClassAttribute() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div class=\\\"flex w-full h-full justify-center items-center hover:bg-blue-50\\\">Multiline class attribute</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc ExtraSpaces() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var2 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var2 == nil {\n\t\t\ttempl_7745c5c3_Var2 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<div class=\\\"a b c\\\">Extra spaces between classes</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc LeadingTrailingSpaces() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<div class=\\\"a b c\\\">Leading and trailing spaces</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc TabsAndNewlines() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<div class=\\\"a b c\\\">Tabs and newlines</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc CaseInsensitive() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<div CLASS=\\\"a b c\\\">Uppercase CLASS attribute</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc OtherAttributesUnchanged() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var6 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var6 == nil {\n\t\t\ttempl_7745c5c3_Var6 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<div data-class=\\\"a  b  c\\\">Non-class attributes unchanged</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc TestComponent() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var7 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var7 == nil {\n\t\t\ttempl_7745c5c3_Var7 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = MultilineClassAttribute().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = ExtraSpaces().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = LeadingTrailingSpaces().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = TabsAndNewlines().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = CaseInsensitive().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = OtherAttributesUnchanged().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-complex-attributes/expected.html",
    "content": "<div\n\tx-data=\"{darkMode: localStorage.getItem('darkMode') || localStorage.setItem('darkMode', 'system')}\"\n\tx-init=\"$watch('darkMode', val => localStorage.setItem('darkMode', val))\"\n\t:class=\"{'dark': darkMode === 'dark' || (darkMode === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)}\"\n></div>\n<div x-data=\"{ count: 0 }\">\n\t<button x-on:click=\"count++\">Increment</button> <span x-text=\"count\"></span>\n</div>\n<div x-data=\"{ count: 0 }\">\n\t<button @click=\"count++\">Increment</button> <span x-text=\"count\"></span>\n</div>\n"
  },
  {
    "path": "generator/test-complex-attributes/render_test.go",
    "content": "package testcomplexattributes\n\nimport (\n\t_ \"embed\"\n\t\"testing\"\n\n\t\"os\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := ComplexAttributes()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-complex-attributes/template.templ",
    "content": "package testcomplexattributes\n\ntempl ComplexAttributes() {\n\t<div\n\t\tx-data=\"{darkMode: localStorage.getItem('darkMode') || localStorage.setItem('darkMode', 'system')}\"\n\t\tx-init=\"$watch('darkMode', val => localStorage.setItem('darkMode', val))\"\n\t\t:class=\"{'dark': darkMode === 'dark' || (darkMode === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)}\"\n\t></div>\n\t<div x-data=\"{ count: 0 }\">\n\t\t<button\n\t\t\tx-on:click=\"count++\"\n\t\t>Increment</button>\n\t\t<span x-text=\"count\"></span>\n\t</div>\n\t<div x-data=\"{ count: 0 }\">\n\t\t<button\n\t\t\t@click=\"count++\"\n\t\t>Increment</button>\n\t\t<span x-text=\"count\"></span>\n\t</div>\n}\n"
  },
  {
    "path": "generator/test-complex-attributes/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcomplexattributes\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc ComplexAttributes() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div x-data=\\\"{darkMode: localStorage.getItem('darkMode') || localStorage.setItem('darkMode', 'system')}\\\" x-init=\\\"$watch('darkMode', val => localStorage.setItem('darkMode', val))\\\" :class=\\\"{'dark': darkMode === 'dark' || (darkMode === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)}\\\"></div><div x-data=\\\"{ count: 0 }\\\"><button x-on:click=\\\"count++\\\">Increment</button> <span x-text=\\\"count\\\"></span></div><div x-data=\\\"{ count: 0 }\\\"><button @click=\\\"count++\\\">Increment</button> <span x-text=\\\"count\\\"></span></div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-constant-attribute-escaping/expected.html",
    "content": "<div>\n\t<!-- valid go escape sequences --><input pattern=\"\\a\" />\n\t<input pattern=\"\\b\" /> <input pattern=\"\\f\" /> <input pattern=\"\\n\" />\n\t<input pattern=\"\\r\" /> <input pattern=\"\\t\" /> <input pattern=\"\\v\" />\n\t<input pattern=\"\\\\\" /> <input pattern=\"\\777\" /> <input pattern=\"\\xFF\" />\n\t<input pattern=\"\\u00FF\" />\n\t<input\n\t\tpattern=\"\\u00FF\\u00FF\\u00FF\"\n\t/><!-- invalid go escape sequences --><input pattern=\"\\s\" />\n</div>\n"
  },
  {
    "path": "generator/test-constant-attribute-escaping/render_test.go",
    "content": "package testconstantattributeescaping\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := BasicTemplate()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-constant-attribute-escaping/template.templ",
    "content": "package testconstantattributeescaping\n\ntempl BasicTemplate() {\n\t<div>\n\t\t<!-- valid go escape sequences -->\n\t\t<input pattern=\"\\a\"/>\n\t\t<input pattern=\"\\b\"/>\n\t\t<input pattern=\"\\f\"/>\n\t\t<input pattern=\"\\n\"/>\n\t\t<input pattern=\"\\r\"/>\n\t\t<input pattern=\"\\t\"/>\n\t\t<input pattern=\"\\v\"/>\n\t\t<input pattern=\"\\\\\"/>\n\t\t<input pattern=\"\\777\"/>\n\t\t<input pattern=\"\\xFF\"/>\n\t\t<input pattern=\"\\u00FF\"/>\n\t\t<input pattern=\"\\u00FF\\u00FF\\u00FF\"/>\n\t\t<!-- invalid go escape sequences -->\n\t\t<input pattern=\"\\s\"/>\n\t</div>\n}\n"
  },
  {
    "path": "generator/test-constant-attribute-escaping/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testconstantattributeescaping\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc BasicTemplate() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div><!-- valid go escape sequences --><input pattern=\\\"\\\\a\\\"> <input pattern=\\\"\\\\b\\\"> <input pattern=\\\"\\\\f\\\"> <input pattern=\\\"\\\\n\\\"> <input pattern=\\\"\\\\r\\\"> <input pattern=\\\"\\\\t\\\"> <input pattern=\\\"\\\\v\\\"> <input pattern=\\\"\\\\\\\\\\\"> <input pattern=\\\"\\\\777\\\"> <input pattern=\\\"\\\\xFF\\\"> <input pattern=\\\"\\\\u00FF\\\"> <input pattern=\\\"\\\\u00FF\\\\u00FF\\\\u00FF\\\"><!-- invalid go escape sequences --><input pattern=\\\"\\\\s\\\"></div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-context/expected.html",
    "content": "<ul>\n\t<li>test</li>\n\t<li>the if passed</li>\n\t<li>the else if passed</li>\n</ul>\n"
  },
  {
    "path": "generator/test-context/render_test.go",
    "content": "package testcontext\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"testing\"\n\n\t\"os\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render()\n\n\tctx := context.WithValue(context.Background(), contextKeyName, \"test\")\n\n\tactual, diff, err := htmldiff.DiffCtx(ctx, component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-context/template.templ",
    "content": "package testcontext\n\ntype contextKey string\n\nvar contextKeyName contextKey = \"name\"\n\ntempl render() {\n\t<ul>\n\t\t<li>{ ctx.Value(contextKeyName).(string) }</li>\n\t\tif ctx.Value(contextKeyName).(string) == \"test\" {\n\t\t\t<li>the if passed</li>\n\t\t}\n\t\tif ctx.Value(contextKeyName).(string) != \"test\" {\n\t\t\t<li>the else if failed</li>\n\t\t} else if ctx.Value(contextKeyName).(string) == \"test\" {\n\t\t\t<li>the else if passed</li>\n\t\t}\n\t</ul>\n}\n"
  },
  {
    "path": "generator/test-context/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcontext\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\ntype contextKey string\n\nvar contextKeyName contextKey = \"name\"\n\nfunc render() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<ul><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(ctx.Value(contextKeyName).(string))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-context/template.templ`, Line: 9, Col: 42}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif ctx.Value(contextKeyName).(string) == \"test\" {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<li>the if passed</li>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\tif ctx.Value(contextKeyName).(string) != \"test\" {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<li>the else if failed</li>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else if ctx.Value(contextKeyName).(string) == \"test\" {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<li>the else if passed</li>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"</ul>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-css-expression/constants.go",
    "content": "package testcssexpression\n\nconst red = \"#ff0000\"\n"
  },
  {
    "path": "generator/test-css-expression/render_test.go",
    "content": "package testcssexpression\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nvar expected = templ.ComponentCSSClass{\n\tID:    \"className_34fc0328\",\n\tClass: templ.SafeCSS(`.className_34fc0328{background-color:#ffffff;max-height:calc(100vh - 170px);color:#ff0000;}`),\n}\n\nfunc TestCSSExpression(t *testing.T) {\n\tif diff := cmp.Diff(expected, className()); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-css-expression/template.templ",
    "content": "package testcssexpression\n\ncss className() {\n\tbackground-color: #ffffff;\n\tmax-height: calc(100vh - 170px);\n\tcolor: { red };\n}\n"
  },
  {
    "path": "generator/test-css-expression/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcssexpression\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc className() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`background-color:#ffffff;`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(`max-height:calc(100vh - 170px);`)\n\ttempl_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, red)))\n\ttempl_7745c5c3_CSSID := templ.CSSID(`className`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-css-middleware/expected.html",
    "content": "<div class=\"red_050e5e03\">Red text</div>\n"
  },
  {
    "path": "generator/test-css-middleware/render_test.go",
    "content": "package testcssmiddleware\n\nimport (\n\t_ \"embed\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"os\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n\t\"github.com/a-h/templ/internal/prettier\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n//go:embed expected.html\nvar expected string\n\nvar expectedCSS = `.red_050e5e03 { color: red; }\n`\n\nfunc Test(t *testing.T) {\n\tvar wg errgroup.Group\n\n\t// Format the expected value.\n\twg.Go(func() (err error) {\n\t\texpected, err = prettier.Run(expected, \"expected.html\", prettier.DefaultCommand())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\n\tcomponent := render(\"Red text\")\n\th := templ.Handler(component)\n\tcssmw := templ.NewCSSMiddleware(h, red())\n\n\t// Create the actual value.\n\tvar actual string\n\twg.Go(func() (err error) {\n\t\tw := httptest.NewRecorder()\n\t\tcssmw.ServeHTTP(w, httptest.NewRequest(\"GET\", \"/\", nil))\n\t\tactual, err = prettier.Run(w.Body.String(), \"actual.html\", prettier.DefaultCommand())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\n\tvar actualCSS string\n\twg.Go(func() (err error) {\n\t\tw := httptest.NewRecorder()\n\t\tcssmw.ServeHTTP(w, httptest.NewRequest(\"GET\", \"/styles/templ.css\", nil))\n\t\tactualCSS, err = prettier.Run(w.Body.String(), \"actual.css\", prettier.DefaultCommand())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\n\tif err := wg.Wait(); err != nil {\n\t\tt.Error(err)\n\t}\n\tactualHTML, diffHTML, err := htmldiff.DiffStrings(expected, actual)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tif diffHTML != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actualHTML), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diffHTML)\n\t}\n\tactualCSSOut, diffCSS, err := htmldiff.DiffStrings(expectedCSS, actualCSS)\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tif diffCSS != \"\" {\n\t\tif err := os.WriteFile(\"actual_css.html\", []byte(actualCSSOut), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual_css.html: %v\", err)\n\t\t}\n\t\tt.Error(diffCSS)\n\t}\n}\n"
  },
  {
    "path": "generator/test-css-middleware/template.templ",
    "content": "package testcssmiddleware\n\ncss red() {\n\tcolor: red;\n}\n\ntempl render(s string) {\n\t<div class={ red }>{ s }</div>\n}\n"
  },
  {
    "path": "generator/test-css-middleware/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcssmiddleware\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc red() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`color:red;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`red`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc render(s string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var2 = []any{red}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-middleware/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(s)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-middleware/template.templ`, Line: 8, Col: 23}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-css-usage/expected.html",
    "content": "<style>\n\t.test {\n\t\tcolor: #ff0000;\n\t}\n</style>\n<div class=\"test\">Style tags are supported</div>\n<style type=\"text/css\">\n\t.cssComponentGreen_58d2872e {\n\t\tcolor: #00ff00;\n\t}\n</style>\n<div class=\"cssComponentGreen_58d2872e\">CSS components are supported</div>\n<div\n\tclass=\"cssComponentGreen_58d2872e classA &amp;&amp;&amp;classB classC d e\"\n\ttype=\"button\"\n>\n\tBoth CSS components and constants are supported\n</div>\n<div\n\tclass=\"cssComponentGreen_58d2872e classA &amp;&amp;&amp;classB classC d e\"\n\ttype=\"button\"\n>\n\tBoth CSS components and constants are supported\n</div>\n<div class=\"a c\">\n\tMaps can be used to determine if a class should be added or not.\n</div>\n<style type=\"text/css\">\n\t.e_739d4573 {\n\t\tfont-size: 14pt;\n\t}\n</style>\n<div class=\"a c e_739d4573\">KV can be used to conditionally set classes.</div>\n<div\n\tclass=\"bg-violet-500 hover:bg-red-600 hover:bg-sky-700 text-[#50d71e] w-[calc(100%-4rem)\"\n>\n\tPseudo attributes and complex class names are supported.\n</div>\n<div class=\"a&#34; onClick=&#34;alert(&#39;hello&#39;)&#34;\">\n\tClass names are HTML escaped.\n</div>\n<style type=\"text/css\">\n\t.loading_a3cc3f08 {\n\t\twidth: 50%;\n\t}\n</style>\n<div class=\"loading_a3cc3f08\">CSS components can be used with arguments.</div>\n<style type=\"text/css\">\n\t.loading_9ccc4ca9 {\n\t\twidth: 100%;\n\t}\n</style>\n<div class=\"loading_9ccc4ca9\">CSS components can be used with arguments.</div>\n<style type=\"text/css\">\n\t.windVaneRotation_b68b990e {\n\t\ttransform: rotate(45deg);\n\t}\n</style>\n<div class=\"windVaneRotation_b68b990e\">Rotate</div>\n"
  },
  {
    "path": "generator/test-css-usage/render_test.go",
    "content": "package testcssusage\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := TestComponent()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-css-usage/template.templ",
    "content": "package testcssusage\n\nimport (\n\t\"fmt\"\n\t\"math\"\n)\n\ntempl StyleTagsAreSupported() {\n\t<style>\n\t\t.test {\n\t\t\tcolor: #ff0000;\n\t\t}\n\t</style>\n\t<div class=\"test\">Style tags are supported</div>\n}\n\n// CSS components.\n\nconst red = \"#00ff00\"\n\ncss cssComponentGreen() {\n\tcolor: { red };\n}\n\ntempl CSSComponentsAreSupported() {\n\t<div class={ cssComponentGreen() }>CSS components are supported</div>\n}\n\n// Both CSS components and constants are supported.\n// Only string names are really required. There is no need to use templ.Class or templ.SafeClass.\ntempl CSSComponentsAndConstantsAreSupported() {\n\t<div class={ cssComponentGreen(), \"classA\", templ.Class(\"&&&classB\"), templ.SafeClass(\"classC\"), \"d e\" } type=\"button\">Both CSS components and constants are supported</div>\n\t// The following is also valid, but not required - you can put the class names in directly.\n\t<div class={ templ.Classes(cssComponentGreen(), \"classA\", templ.Class(\"&&&classB\"), templ.SafeClass(\"classC\")), \"d e\" } type=\"button\">Both CSS components and constants are supported</div>\n}\n\n// Maps can be used to determine if a class should be added or not.\ntempl MapsCanBeUsedToConditionallySetClasses() {\n\t<div class={ map[string]bool{\"a\": true, \"b\": false, \"c\": true} }>Maps can be used to determine if a class should be added or not.</div>\n}\n\n// The templ.KV function can be used to add a class if a condition is true.\n\ncss d() {\n\tfont-size: 12pt;\n}\n\ncss e() {\n\tfont-size: 14pt;\n}\n\ntempl KVCanBeUsedToConditionallySetClasses() {\n\t<div class={ \"a\", templ.KV(\"b\", false), \"c\", templ.KV(d(), false), templ.KV(e(), true) }>KV can be used to conditionally set classes.</div>\n}\n\n// Pseudo attributes can be used without any special syntax.\ntempl PseudoAttributesAndComplexClassNamesAreSupported() {\n\t<div class={ \"bg-violet-500\", \"hover:bg-red-600\", \"hover:bg-sky-700\", \"text-[#50d71e]\", \"w-[calc(100%-4rem)\" }>Pseudo attributes and complex class names are supported.</div>\n}\n\n// Class names are HTML escaped.\ntempl ClassNamesAreHTMLEscaped() {\n\t<div class={ \"a\\\" onClick=\\\"alert('hello')\\\"\" }>Class names are HTML escaped.</div>\n}\n\n// CSS components can be used with arguments.\n\ncss loading(percent int) {\n\twidth: { fmt.Sprintf(\"%d%%\", percent) };\n}\n\ntempl CSSComponentsCanBeUsedWithArguments() {\n\t<div class={ loading(50) }>CSS components can be used with arguments.</div>\n\t<div class={ loading(100) }>CSS components can be used with arguments.</div>\n}\n\ncss windVaneRotation(degrees float64) {\n\ttransform: { templ.SafeCSSProperty(fmt.Sprintf(\"rotate(%ddeg)\", int(math.Round(degrees)))) };\n}\n\ntempl Rotate(degrees float64) {\n\t<div class={ windVaneRotation(degrees) }>Rotate</div>\n}\n\n// Combine all tests.\ntempl TestComponent() {\n\t@StyleTagsAreSupported()\n\t@CSSComponentsAreSupported()\n\t@CSSComponentsAndConstantsAreSupported()\n\t@MapsCanBeUsedToConditionallySetClasses()\n\t@KVCanBeUsedToConditionallySetClasses()\n\t@PseudoAttributesAndComplexClassNamesAreSupported()\n\t@ClassNamesAreHTMLEscaped()\n\t@CSSComponentsCanBeUsedWithArguments()\n\t@Rotate(45)\n}\n"
  },
  {
    "path": "generator/test-css-usage/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcssusage\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport (\n\t\"fmt\"\n\t\"math\"\n)\n\nfunc StyleTagsAreSupported() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<style>\\n\\t\\t.test {\\n\\t\\t\\tcolor: #ff0000;\\n\\t\\t}\\n\\t</style><div class=\\\"test\\\">Style tags are supported</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// CSS components.\n\nconst red = \"#00ff00\"\n\nfunc cssComponentGreen() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, red)))\n\ttempl_7745c5c3_CSSID := templ.CSSID(`cssComponentGreen`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc CSSComponentsAreSupported() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var2 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var2 == nil {\n\t\t\ttempl_7745c5c3_Var2 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var3 = []any{cssComponentGreen()}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var3).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\">CSS components are supported</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// Both CSS components and constants are supported.\n// Only string names are really required. There is no need to use templ.Class or templ.SafeClass.\nfunc CSSComponentsAndConstantsAreSupported() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var6 = []any{cssComponentGreen(), \"classA\", templ.Class(\"&&&classB\"), templ.SafeClass(\"classC\"), \"d e\"}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 string\n\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"\\\" type=\\\"button\\\">Both CSS components and constants are supported</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var8 = []any{templ.Classes(cssComponentGreen(), \"classA\", templ.Class(\"&&&classB\"), templ.SafeClass(\"classC\")), \"d e\"}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var9 string\n\t\ttempl_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var8).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\" type=\\\"button\\\">Both CSS components and constants are supported</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// Maps can be used to determine if a class should be added or not.\nfunc MapsCanBeUsedToConditionallySetClasses() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var10 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var10 == nil {\n\t\t\ttempl_7745c5c3_Var10 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var11 = []any{map[string]bool{\"a\": true, \"b\": false, \"c\": true}}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var11...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var12 string\n\t\ttempl_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var11).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"\\\">Maps can be used to determine if a class should be added or not.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// The templ.KV function can be used to add a class if a condition is true.\nfunc d() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`font-size:12pt;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`d`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc e() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`font-size:14pt;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`e`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc KVCanBeUsedToConditionallySetClasses() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var13 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var13 == nil {\n\t\t\ttempl_7745c5c3_Var13 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var14 = []any{\"a\", templ.KV(\"b\", false), \"c\", templ.KV(d(), false), templ.KV(e(), true)}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var15 string\n\t\ttempl_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var14).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"\\\">KV can be used to conditionally set classes.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// Pseudo attributes can be used without any special syntax.\nfunc PseudoAttributesAndComplexClassNamesAreSupported() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var16 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var16 == nil {\n\t\t\ttempl_7745c5c3_Var16 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var17 = []any{\"bg-violet-500\", \"hover:bg-red-600\", \"hover:bg-sky-700\", \"text-[#50d71e]\", \"w-[calc(100%-4rem)\"}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var18 string\n\t\ttempl_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var17).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"\\\">Pseudo attributes and complex class names are supported.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// Class names are HTML escaped.\nfunc ClassNamesAreHTMLEscaped() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var19 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var19 == nil {\n\t\t\ttempl_7745c5c3_Var19 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var20 = []any{\"a\\\" onClick=\\\"alert('hello')\\\"\"}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var21 string\n\t\ttempl_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var20).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, \"\\\">Class names are HTML escaped.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// CSS components can be used with arguments.\nfunc loading(percent int) templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`width`, fmt.Sprintf(\"%d%%\", percent))))\n\ttempl_7745c5c3_CSSID := templ.CSSID(`loading`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc CSSComponentsCanBeUsedWithArguments() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var22 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var22 == nil {\n\t\t\ttempl_7745c5c3_Var22 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var23 = []any{loading(50)}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var23...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var24 string\n\t\ttempl_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var23).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, \"\\\">CSS components can be used with arguments.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var25 = []any{loading(100)}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var25...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var26 string\n\t\ttempl_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var25).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, \"\\\">CSS components can be used with arguments.</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc windVaneRotation(degrees float64) templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`transform`, templ.SafeCSSProperty(fmt.Sprintf(\"rotate(%ddeg)\", int(math.Round(degrees)))))))\n\ttempl_7745c5c3_CSSID := templ.CSSID(`windVaneRotation`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc Rotate(degrees float64) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var27 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var27 == nil {\n\t\t\ttempl_7745c5c3_Var27 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var28 = []any{windVaneRotation(degrees)}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var28...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, \"<div class=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var29 string\n\t\ttempl_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var28).String())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-css-usage/template.templ`, Line: 1, Col: 0}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, \"\\\">Rotate</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// Combine all tests.\nfunc TestComponent() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var30 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var30 == nil {\n\t\t\ttempl_7745c5c3_Var30 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = StyleTagsAreSupported().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = CSSComponentsAreSupported().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = CSSComponentsAndConstantsAreSupported().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = MapsCanBeUsedToConditionallySetClasses().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = KVCanBeUsedToConditionallySetClasses().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = PseudoAttributesAndComplexClassNamesAreSupported().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = ClassNamesAreHTMLEscaped().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = CSSComponentsCanBeUsedWithArguments().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Rotate(45).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-doctype/expected.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<title>title</title>\n\t</head>\n\t<body>\n\t\tcontent\n\t</body>\n</html>\n"
  },
  {
    "path": "generator/test-doctype/render_test.go",
    "content": "package testdoctype\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := Layout(\"title\", \"content\")\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-doctype/template.templ",
    "content": "package testdoctype\n\ntempl Layout(title, content string) {\n\t<!DOCTYPE html>\n\t<html lang=\"en\">\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<title>{ title }</title>\n\t\t</head>\n\t\t<body>{ content }</body>\n\t</html>\n}\n"
  },
  {
    "path": "generator/test-doctype/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testdoctype\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Layout(title, content string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype html><html lang=\\\"en\\\"><head><meta charset=\\\"UTF-8\\\"><meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge\\\"><meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"><title>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-doctype/template.templ`, Line: 10, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</title></head><body>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(content)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-doctype/template.templ`, Line: 12, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-doctype-html4/expected.html",
    "content": "<!doctype html PUBLIC \"http://www.w3.org/TR/html4/loose.dtd\">\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<title>title</title>\n\t</head>\n\t<body>\n\t\tcontent\n\t</body>\n</html>\n"
  },
  {
    "path": "generator/test-doctype-html4/render_test.go",
    "content": "package testdoctype\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := Layout(\"title\", \"content\")\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-doctype-html4/template.templ",
    "content": "package testdoctype\n\ntempl Layout(title, content string) {\n\t<!DOCTYPE HTML PUBLIC \"http://www.w3.org/TR/html4/loose.dtd\">\n\t<html lang=\"en\">\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<title>{ title }</title>\n\t\t</head>\n\t\t<body>{ content }</body>\n\t</html>\n}\n"
  },
  {
    "path": "generator/test-doctype-html4/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testdoctype\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Layout(title, content string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype HTML PUBLIC \\\"http://www.w3.org/TR/html4/loose.dtd\\\"><html lang=\\\"en\\\"><head><meta charset=\\\"UTF-8\\\"><meta http-equiv=\\\"X-UA-Compatible\\\" content=\\\"IE=edge\\\"><meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"><title>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-doctype-html4/template.templ`, Line: 10, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</title></head><body>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(content)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-doctype-html4/template.templ`, Line: 12, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-element-attributes/data.go",
    "content": "package testelementattributes\n\ntype person struct {\n\tname      string\n\temail     string\n\timportant bool\n}\n"
  },
  {
    "path": "generator/test-element-attributes/expected.html",
    "content": "<style type=\"text/css\">\n\t.important_2ed176fc {\n\t\twidth: 100;\n\t}\n</style>\n<div style=\"width: 100\">Important</div>\n<style type=\"text/css\">\n\t.unimportant_900aeb18 {\n\t\twidth: 50;\n\t}\n</style>\n<div style=\"width: 100\" class=\"unimportant_900aeb18\">Unimportant</div>\n<div style=\"width: 100\" class=\"unimportant_900aeb18\">Else</div>\n<div\n\tdata-script=\"on click\n                do something\n             end\"\n></div>\n<h2>htmx Wildcard attribute</h2>\n<form\n\tdynamic-attr-key=\"hello world\"\n\tdynamic-const-key=\"hello world\"\n\tmy-string-attr\n\tbool-attr\n\thx-post=\"/api/secret/unlock\"\n\thx-target=\"#secret\"\n\thx-target-*=\"#errors\"\n\thx-indicator=\"#loading-indicator\"\n>\n\t<input type=\"button\" value=\"Unlock\" />\n</form>\n"
  },
  {
    "path": "generator/test-element-attributes/render_test.go",
    "content": "package testelementattributes\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(person{\n\t\tname:  \"Luiz Bonfa\",\n\t\temail: \"luiz@example.com\",\n\t})\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-element-attributes/template.templ",
    "content": "package testelementattributes\n\ncss important() {\n\twidth: 100;\n}\n\ncss unimportant() {\n\twidth: 50;\n}\n\ntempl render(p person) {\n\t<div\n\t\tstyle=\"width: 100;\"\n\t\tif p.important {\n\t\t\tclass={ important() }\n\t\t}\n\t>Important</div>\n\t<div\n\t\tstyle=\"width: 100;\"\n\t\tif !p.important {\n\t\t\tclass={ unimportant }\n\t\t}\n\t>Unimportant</div>\n\t<div\n\t\tstyle=\"width: 100;\"\n\t\tif p.important {\n\t\t\tclass={ important }\n\t\t} else {\n\t\t\tclass={ unimportant }\n\t\t}\n\t>Else</div>\n\t<div\n\t\tdata-script=\"on click\n                do something\n             end\"\n\t></div>\n\t<h2>htmx Wildcard attribute</h2>\n\t<form\n\t\t{ \"dynamic\"+\"-attr-key\" }={ \"hello world\" }\n\t\t{ \"dynamic\"+\"-const-key\" }=\"hello world\"\n\t\t{ \"my-string\" + \"-attr\" }\n\t\t{ \"bool-\" + \"attr\" }?={ true }\n\t\t{ \"bool-\" + \"attr-false\" }?={ false }\n\t\thx-post=\"/api/secret/unlock\"\n\t\thx-target=\"#secret\"\n\t\thx-target-*=\"#errors\"\n\t\thx-indicator=\"#loading-indicator\"\n\t>\n\t\t<input type=\"button\" value=\"Unlock\"/>\n\t</form>\n}\n"
  },
  {
    "path": "generator/test-element-attributes/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testelementattributes\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc important() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`width:100;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`important`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc unimportant() templ.CSSClass {\n\ttempl_7745c5c3_CSSBuilder := templruntime.GetBuilder()\n\ttempl_7745c5c3_CSSBuilder.WriteString(`width:50;`)\n\ttempl_7745c5c3_CSSID := templ.CSSID(`unimportant`, templ_7745c5c3_CSSBuilder.String())\n\treturn templ.ComponentCSSClass{\n\t\tID:    templ_7745c5c3_CSSID,\n\t\tClass: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),\n\t}\n}\n\nfunc render(p person) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tvar templ_7745c5c3_Var2 = []any{important()}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div style=\\\"width: 100;\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif p.important {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \" class=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 1, Col: 0}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \">Important</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 = []any{unimportant}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<div style=\\\"width: 100;\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif !p.important {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \" class=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var5 string\n\t\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 1, Col: 0}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \">Unimportant</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 = []any{important}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 = []any{unimportant}\n\t\ttempl_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"<div style=\\\"width: 100;\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif p.important {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \" class=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var8 string\n\t\t\ttempl_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 1, Col: 0}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \" class=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var9 string\n\t\t\ttempl_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var7).String())\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 1, Col: 0}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, \">Else</div><div data-script=\\\"on click\\n                do something\\n             end\\\"></div><h2>htmx Wildcard attribute</h2><form\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var10 string\n\t\ttempl_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(\"dynamic\" + \"-attr-key\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 39, Col: 25}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(` ` + templ_7745c5c3_Var10))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, \"=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var11 string\n\t\ttempl_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(\"hello world\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 39, Col: 43}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, \"\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var12 string\n\t\ttempl_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(\"dynamic\" + \"-const-key\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 40, Col: 26}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(` ` + templ_7745c5c3_Var12))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, \"=\\\"hello world\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var13 string\n\t\ttempl_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(\"my-string\" + \"-attr\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 41, Col: 25}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(` ` + templ_7745c5c3_Var13))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\tvar templ_7745c5c3_Var14 string\n\t\t\ttempl_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(\"bool-\" + \"attr\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 42, Col: 20}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(` ` + templ_7745c5c3_Var14))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\tif false {\n\t\t\tvar templ_7745c5c3_Var15 string\n\t\t\ttempl_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(\"bool-\" + \"attr-false\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-element-attributes/template.templ`, Line: 43, Col: 26}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(` ` + templ_7745c5c3_Var15))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, \" hx-post=\\\"/api/secret/unlock\\\" hx-target=\\\"#secret\\\" hx-target-*=\\\"#errors\\\" hx-indicator=\\\"#loading-indicator\\\"><input type=\\\"button\\\" value=\\\"Unlock\\\"></form>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-elseif/data.go",
    "content": "package elseif\n\ntype data struct {\n}\n\nfunc (d data) IsTrue() bool {\n\treturn false\n}\n"
  },
  {
    "path": "generator/test-elseif/expected.html",
    "content": "<div>False</div>\n<div>ElseIf</div>\n<div>OK</div>\n"
  },
  {
    "path": "generator/test-elseif/render_test.go",
    "content": "package elseif\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(data{})\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-elseif/template.templ",
    "content": "package elseif\n\ntempl render(d data) {\n\t<div>\n\t\tif d.IsTrue() {\n\t\t\t{ \"True\" }\n\t\t} else if !d.IsTrue() {\n\t\t\t{ \"False\" }\n\t\t} else {\n\t\t\t{ \"Else\" }\n\t\t}\n\t</div>\n\t<div>\n\t\tif 1 == 2 {\n\t\t\t{ \"If\" }\n\t\t} else if true {\n\t\t\t{ \"ElseIf\" }\n\t\t}\n\t</div>\n\t<div>\n\t\tif 1 == 2 {\n\t\t\t{ \"If\" }\n\t\t} else if 1 == 3 {\n\t\t\t{ \"ElseIf\" }\n\t\t} else if 1 == 4 {\n\t\t\t{ \"ElseIf\" }\n\t\t} else if true {\n\t\t\t{ \"OK\" }\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "generator/test-elseif/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage elseif\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(d data) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif d.IsTrue() {\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(\"True\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 6, Col: 11}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else if !d.IsTrue() {\n\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(\"False\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 8, Col: 12}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else {\n\t\t\tvar templ_7745c5c3_Var4 string\n\t\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(\"Else\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 10, Col: 11}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div><div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif 1 == 2 {\n\t\t\tvar templ_7745c5c3_Var5 string\n\t\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(\"If\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 15, Col: 9}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else if true {\n\t\t\tvar templ_7745c5c3_Var6 string\n\t\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(\"ElseIf\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 17, Col: 13}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</div><div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif 1 == 2 {\n\t\t\tvar templ_7745c5c3_Var7 string\n\t\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(\"If\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 22, Col: 9}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else if 1 == 3 {\n\t\t\tvar templ_7745c5c3_Var8 string\n\t\t\ttempl_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(\"ElseIf\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 24, Col: 13}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else if 1 == 4 {\n\t\t\tvar templ_7745c5c3_Var9 string\n\t\t\ttempl_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(\"ElseIf\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 26, Col: 13}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else if true {\n\t\t\tvar templ_7745c5c3_Var10 string\n\t\t\ttempl_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(\"OK\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-elseif/template.templ`, Line: 28, Col: 9}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-for/expected.html",
    "content": "<div>a</div>\n<div>b</div>\n<div>c</div>\n"
  },
  {
    "path": "generator/test-for/render_test.go",
    "content": "package testfor\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render([]string{\"a\", \"b\", \"c\"})\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-for/template.templ",
    "content": "package testfor\n\ntempl render(items []string) {\n\tfor _, item := range items {\n\t\t<div>{ item }</div>\n\t}\n}\n"
  },
  {
    "path": "generator/test-for/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testfor\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(items []string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tfor _, item := range items {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(item)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-for/template.templ`, Line: 5, Col: 13}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-form-action/expected.html",
    "content": "<form action=\"javascript:alert('unaffected');\">Ignored</form>\n<form action=\"about:invalid#TemplFailedSanitizationURL\">Sanitized</form>\n<form action=\"javascript:alert(&#39;should not be sanitized&#39;)\">\n\tUnsanitized\n</form>\n<form action=\"javascript:alert(&#39;should not be sanitized&#39;)\">\n\twith error unsanitized\n</form>\n<form action=\"about:invalid#TemplFailedSanitizationURL\">\n\twith error sanitized\n</form>\n"
  },
  {
    "path": "generator/test-form-action/render_test.go",
    "content": "package testahref\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-form-action/template.templ",
    "content": "package testahref\n\ntempl render() {\n\t<form action=\"javascript:alert('unaffected');\">Ignored</form>\n\t<form action={ templ.URL(\"javascript:alert('should be sanitized')\") }>Sanitized</form>\n\t<form action={ templ.SafeURL(\"javascript:alert('should not be sanitized')\") }>Unsanitized</form>\n\t<form action={ safeUrl(\"javascript:alert('should not be sanitized')\") }>with error unsanitized</form>\n\t<form action={ stringUrl(\"javascript:alert('should be sanitized')\") }>with error sanitized</form>\n}\n\nfunc safeUrl(s string) (templ.SafeURL, error) {\n\treturn templ.SafeURL(s), nil\n}\n\nfunc stringUrl(s string) (string, error) {\n\treturn s, nil\n}\n"
  },
  {
    "path": "generator/test-form-action/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testahref\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<form action=\\\"javascript:alert('unaffected');\\\">Ignored</form><form action=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.SafeURL\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(\"javascript:alert('should be sanitized')\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-form-action/template.templ`, Line: 5, Col: 68}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">Sanitized</form><form action=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 templ.SafeURL\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(\"javascript:alert('should not be sanitized')\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-form-action/template.templ`, Line: 6, Col: 76}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\">Unsanitized</form><form action=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 templ.SafeURL\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(safeUrl(\"javascript:alert('should not be sanitized')\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-form-action/template.templ`, Line: 7, Col: 70}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\">with error unsanitized</form><form action=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 templ.SafeURL\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinURLErrs(stringUrl(\"javascript:alert('should be sanitized')\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-form-action/template.templ`, Line: 8, Col: 68}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"\\\">with error sanitized</form>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc safeUrl(s string) (templ.SafeURL, error) {\n\treturn templ.SafeURL(s), nil\n}\n\nfunc stringUrl(s string) (string, error) {\n\treturn s, nil\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-fragment/complete.html",
    "content": "<div>Page Header</div>\n<div>Fragment Content A</div>\n<div>Fragment Content B</div>\n<div>Outer Fragment Start</div>\n<div>Inner Fragment Content</div>\n<div>Outer Fragment End</div>\n<div>Page Footer</div>\n"
  },
  {
    "path": "generator/test-fragment/render_test.go",
    "content": "package testfragment\n\nimport (\n\t_ \"embed\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"os\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed complete.html\nvar complete string\n\nfunc Test(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\thandler  http.Handler\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"complete pages can be rendered\",\n\t\t\thandler:  templ.Handler(Page()),\n\t\t\texpected: complete,\n\t\t},\n\t\t{\n\t\t\tname:     \"single fragments can be rendered\",\n\t\t\thandler:  templ.Handler(Page(), templ.WithFragments(\"content-a\")),\n\t\t\texpected: `<div>Fragment Content A</div>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"multiple fragments can be rendered\",\n\t\t\thandler:  templ.Handler(Page(), templ.WithFragments(\"content-a\", \"content-b\")),\n\t\t\texpected: `<div>Fragment Content A</div><div>Fragment Content B</div>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"outer fragments render their contents, even if inner fragments are not requested\",\n\t\t\thandler:  templ.Handler(Page(), templ.WithFragments(\"outer\")),\n\t\t\texpected: `<div>Outer Fragment Start</div><div>Inner Fragment Content</div><div>Outer Fragment End</div>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"inner fragments can be rendered without the outer fragment\",\n\t\t\thandler:  templ.Handler(Page(), templ.WithFragments(\"inner\")),\n\t\t\texpected: `<div>Inner Fragment Content</div>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"fragments that don't exist return an empty string\",\n\t\t\thandler:  templ.Handler(Page(), templ.WithFragments(\"non-existent\")),\n\t\t\texpected: \"\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tw := httptest.NewRecorder()\n\t\t\tr := httptest.NewRequest(\"GET\", \"/\", nil)\n\t\t\ttt.handler.ServeHTTP(w, r)\n\n\t\t\tif actualStatusCode := w.Result().StatusCode; http.StatusOK != actualStatusCode {\n\t\t\t\tt.Errorf(\"expected status %d, got %d\", http.StatusOK, actualStatusCode)\n\t\t\t}\n\n\t\t\tbody, err := io.ReadAll(w.Result().Body)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to read body: %v\", err)\n\t\t\t}\n\n\t\t\tactual, diff, err := htmldiff.DiffStrings(tt.expected, string(body))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to diff: %v\", err)\n\t\t\t}\n\t\t\tif diff != \"\" {\n\t\t\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t\t\t}\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "generator/test-fragment/template.templ",
    "content": "package testfragment\n\ntempl Page() {\n\t<div>Page Header</div>\n\t@templ.Fragment(\"content-a\") {\n\t\t<div>Fragment Content A</div>\n\t}\n\t@templ.Fragment(\"content-b\") {\n\t\t<div>Fragment Content B</div>\n\t}\n\t@templ.Fragment(\"outer\") {\n\t\t<div>Outer Fragment Start</div>\n\t\t@templ.Fragment(\"inner\") {\n\t\t\t<div>Inner Fragment Content</div>\n\t\t}\n\t\t<div>Outer Fragment End</div>\n\t}\n\t<div>Page Footer</div>\n}\n"
  },
  {
    "path": "generator/test-fragment/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testfragment\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Page() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Page Header</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<div>Fragment Content A</div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = templ.Fragment(\"content-a\").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<div>Fragment Content B</div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = templ.Fragment(\"content-b\").Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<div>Outer Fragment Start</div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t}\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<div>Inner Fragment Content</div>\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\ttempl_7745c5c3_Err = templ.Fragment(\"inner\").Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \" <div>Outer Fragment End</div>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = templ.Fragment(\"outer\").Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"<div>Page Footer</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-go-comments/expected.html",
    "content": "<p>sample content</p>\n"
  },
  {
    "path": "generator/test-go-comments/render_test.go",
    "content": "package testcomment\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(\"sample content\")\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-go-comments/template.templ",
    "content": "package testcomment\n\ntempl render(content string) {\n\t// This is not rendered.\n\t<p>{ content }</p>\n\t/*\n\t\tThis is also not rendered.\n\t*/\n\t/* Neither is this */\n}\n"
  },
  {
    "path": "generator/test-go-comments/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcomment\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(content string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(content)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-go-comments/template.templ`, Line: 5, Col: 13}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-go-template-in-templ/expected.html",
    "content": "<!doctype html>\n<html>\n\t<body>\n\t\t<div>Hello, World!</div>\n\t</body>\n</html>\n"
  },
  {
    "path": "generator/test-go-template-in-templ/render_test.go",
    "content": "package testgotemplates\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc TestExample(t *testing.T) {\n\tcomponent := Example()\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-go-template-in-templ/template.templ",
    "content": "package testgotemplates\n\nimport \"html/template\"\n\nvar goTemplate = template.Must(template.New(\"example\").Parse(\"<div>{{ . }}</div>\"))\n\ntempl Example() {\n\t<!DOCTYPE html>\n\t<html>\n\t\t<body>\n\t\t\t@templ.FromGoHTML(goTemplate, \"Hello, World!\")\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "generator/test-go-template-in-templ/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testgotemplates\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"html/template\"\n\nvar goTemplate = template.Must(template.New(\"example\").Parse(\"<div>{{ . }}</div>\"))\n\nfunc Example() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!doctype html><html><body>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.FromGoHTML(goTemplate, \"Hello, World!\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-html/data.go",
    "content": "package testhtml\n\ntype person struct {\n\tname  string\n\temail string\n}\n"
  },
  {
    "path": "generator/test-html/expected.html",
    "content": "<div>\n\t<h1>Luiz Bonfa</h1>\n\t<div\n\t\tstyle=\"font-family: &quot;sans-serif&quot;\"\n\t\tid=\"test\"\n\t\tdata-contents=\"something with &#34;quotes&#34; and a &lt;tag&gt;\"\n\t>\n\t\t<div>email:<a href=\"mailto: luiz@example.com\">luiz@example.com</a></div>\n\t</div>\n</div>\n<hr noshade />\n<hr optionA optionB optionC=\"other\" />\n<hr noshade />\n<input name=\"test\" />Text\n"
  },
  {
    "path": "generator/test-html/render_test.go",
    "content": "package testhtml\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(person{\n\t\tname:  \"Luiz Bonfa\",\n\t\temail: \"luiz@example.com\",\n\t})\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-html/template.templ",
    "content": "package testhtml\n\ntempl render(p person) {\n\t<div>\n\t\t<h1>{ p.name }</h1>\n\t\t<div style=\"font-family: 'sans-serif'\" id=\"test\" data-contents={ `something with \"quotes\" and a <tag>` }>\n\t\t\t<div>email:<a href={ templ.URL(\"mailto: \" + p.email) }>{ p.email }</a></div>\n\t\t</div>\n\t</div>\n\t<hr noshade?={ true }/>\n\t<hr optionA optionB?={ true } optionC=\"other\" optionD?={ false }/>\n\t<hr noshade/>\n\t<input name=\"test\"/>Text\n}\n"
  },
  {
    "path": "generator/test-html/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testhtml\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(p person) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div><h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(p.name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-html/template.templ`, Line: 5, Col: 14}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</h1><div style=\\\"font-family: 'sans-serif'\\\" id=\\\"test\\\" data-contents=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(`something with \"quotes\" and a <tag>`)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-html/template.templ`, Line: 6, Col: 104}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\"><div>email:<a href=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 templ.SafeURL\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(\"mailto: \" + p.email))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-html/template.templ`, Line: 7, Col: 55}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.email)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-html/template.templ`, Line: 7, Col: 67}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</a></div></div></div><hr\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \" noshade\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"><hr optionA\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \" optionB\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \" optionC=\\\"other\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif false {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \" optionD\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"><hr noshade><input name=\\\"test\\\">Text\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-html-comment/expected.html",
    "content": "<!-- simple html comment -->\n<p>sample content</p>\n<!--\n\t\tmultiline\n\t\tcomment\n\t-->\n<p>second paragraph</p>\n<!--\n\t\t@paragraph(\"commented out composed element\")\n\t-->\n<p>third paragraph</p>\n<!-- commented out string expression: { content } --><span>sample content</span\n><!-- <div>comment with html</div> -->\n"
  },
  {
    "path": "generator/test-html-comment/render_test.go",
    "content": "package testcomment\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(\"sample content\")\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-html-comment/template.templ",
    "content": "package testcomment\n\ntempl render(content string) {\n\t<!-- simple html comment -->\n\t@paragraph(content)\n\t<!--\n\t\tmultiline\n\t\tcomment\n\t-->\n\t@paragraph(\"second paragraph\")\n\t<!--\n\t\t@paragraph(\"commented out composed element\")\n\t-->\n\t@paragraph(\"third paragraph\")\n\t<!-- commented out string expression: { content } -->\n\t<span>{ content }</span>\n\t<!-- <div>comment with html</div> -->\n}\n\ntempl paragraph(content string) {\n\t<p>{ content }</p>\n}\n"
  },
  {
    "path": "generator/test-html-comment/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testcomment\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(content string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<!-- simple html comment -->\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = paragraph(content).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<!--\\n\\t\\tmultiline\\n\\t\\tcomment\\n\\t-->\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = paragraph(\"second paragraph\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<!--\\n\\t\\t@paragraph(\\\"commented out composed element\\\")\\n\\t-->\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = paragraph(\"third paragraph\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<!-- commented out string expression: { content } --><span>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(content)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-html-comment/template.templ`, Line: 16, Col: 16}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</span><!-- <div>comment with html</div> -->\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc paragraph(content string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(content)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-html-comment/template.templ`, Line: 21, Col: 13}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"</p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-if/data.go",
    "content": "package testif\n\ntype data struct {\n}\n\nfunc (d data) IsTrue() bool {\n\treturn true\n}\n"
  },
  {
    "path": "generator/test-if/expected.html",
    "content": "True\n"
  },
  {
    "path": "generator/test-if/render_test.go",
    "content": "package testif\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(data{})\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-if/template.templ",
    "content": "package testif\n\ntempl render(d data) {\n\tif d.IsTrue() {\n\t\t{ \"True\" }\n\t} else {\n\t\t{ \"False\" }\n\t}\n}\n"
  },
  {
    "path": "generator/test-if/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testif\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(d data) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tif d.IsTrue() {\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(\"True\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-if/template.templ`, Line: 5, Col: 10}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else {\n\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(\"False\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-if/template.templ`, Line: 7, Col: 11}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-ifelse/data.go",
    "content": "package ifelse\n\ntype data struct {\n}\n\nfunc (d data) IsTrue() bool {\n\treturn false\n}\n"
  },
  {
    "path": "generator/test-ifelse/expected.html",
    "content": "False\n"
  },
  {
    "path": "generator/test-ifelse/render_test.go",
    "content": "package ifelse\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(data{})\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-ifelse/template.templ",
    "content": "package ifelse\n\ntempl render(d data) {\n\tif d.IsTrue() {\n\t\t{ \"True\" }\n\t} else {\n\t\t{ \"False\" }\n\t}\n}\n"
  },
  {
    "path": "generator/test-ifelse/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage ifelse\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(d data) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tif d.IsTrue() {\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(\"True\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-ifelse/template.templ`, Line: 5, Col: 10}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else {\n\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(\"False\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-ifelse/template.templ`, Line: 7, Col: 11}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-import/expected.html",
    "content": "<ul>\n\t<li><u>Item 1</u></li>\n\t<li><u>Item 2</u></li>\n\t<li><u>Item 3</u></li>\n</ul>\n"
  },
  {
    "path": "generator/test-import/render_test.go",
    "content": "package testimport\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := main()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-import/template.templ",
    "content": "package testimport\n\ntempl listItem() {\n\t<li>\n\t\t{ children... }\n\t</li>\n}\n\ntempl list() {\n\t<ul>\n\t\t{ children... }\n\t</ul>\n}\n\ntempl main() {\n\t@list() {\n\t\t@listItem() {\n\t\t\t<u>Item 1</u>\n\t\t}\n\t\t@listItem() {\n\t\t\t<u>Item 2</u>\n\t\t}\n\t\t@listItem() {\n\t\t\t<u>Item 3</u>\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "generator/test-import/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testimport\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc listItem() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc list() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var2 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var2 == nil {\n\t\t\ttempl_7745c5c3_Var2 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<ul>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ_7745c5c3_Var2.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</ul>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc main() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t}\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<u>Item 1</u>\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\ttempl_7745c5c3_Err = listItem().Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \" \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t}\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"<u>Item 2</u>\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\ttempl_7745c5c3_Err = listItem().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \" \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Var7 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t}\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"<u>Item 3</u>\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\ttempl_7745c5c3_Err = listItem().Render(templ.WithChildren(ctx, templ_7745c5c3_Var7), templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = list().Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-js-unsafe-usage/expected.html",
    "content": "<button onClick=\"anythingILike(&#39;blah&#39;)\">Click me</button>\n<script>\n\t// Arbitrary JS code\n</script>\n"
  },
  {
    "path": "generator/test-js-unsafe-usage/render_test.go",
    "content": "package testjsunsafeusage\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := TestComponent()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-js-unsafe-usage/template.templ",
    "content": "package testjsunsafeusage\n\ntempl TestComponent() {\n\t<button onClick={ templ.JSUnsafeFuncCall(\"anythingILike('blah')\") }>Click me</button>\n\t@templ.JSUnsafeFuncCall(\"// Arbitrary JS code\")\n}\n"
  },
  {
    "path": "generator/test-js-unsafe-usage/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testjsunsafeusage\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc TestComponent() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSUnsafeFuncCall(\"anythingILike('blah')\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<button onClick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.ComponentScript = templ.JSUnsafeFuncCall(\"anythingILike('blah')\")\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">Click me</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.JSUnsafeFuncCall(\"// Arbitrary JS code\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-js-usage/expected.html",
    "content": "<button onClick=\"alert(&#34;Hello, World!&#34;)\">Click me</button>\n<script>\n\tfunction customAlert(msg, date) {\n\t\talert(msg + \" \" + date);\n\t}\n</script>\n<button\n\tonClick=\"customAlert(&#34;Hello, custom alert 1: &#34;,&#34;2020-01-01T00:00:00Z&#34;)\"\n>\n\tClick me\n</button>\n<button\n\tonClick=\"customAlert(&#34;Hello, custom alert 2: &#34;,&#34;2020-01-01T00:00:00Z&#34;)\"\n>\n\tClick me\n</button>\n<script>\n\tcustomAlert(\"Runs on page load\", \"2020-01-01T00:00:00Z\");\n</script>\n<script>\n\tfunction onClickEventHandler(event, data) {\n\t\talert(event.type);\n\t\talert(data);\n\t\tevent.preventDefault();\n\t}\n</script>\n<button onclick=\"onClickEventHandler(event,&#34;1234&#34;)\">\n\tPass event handler\n</button>\n"
  },
  {
    "path": "generator/test-js-usage/render_test.go",
    "content": "package testjsusage\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := TestComponent()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-js-usage/template.templ",
    "content": "package testjsusage\n\nimport \"time\"\n\nvar onceHandle = templ.NewOnceHandle()\n\ntempl TestComponent() {\n\t<button onClick={ templ.JSFuncCall(\"alert\", \"Hello, World!\") }>Click me</button>\n\t@onceHandle.Once() {\n\t\t<script>\n\t\t\tfunction customAlert(msg, date) {\n\t\t\t\talert(msg + \" \" + date);\n\t\t\t}\n\t\t</script>\n\t}\n\t<button onClick={ templ.JSFuncCall(\"customAlert\", \"Hello, custom alert 1: \", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)) }>Click me</button>\n\t<button onClick={ templ.JSFuncCall(\"customAlert\", \"Hello, custom alert 2: \", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)) }>Click me</button>\n\t@templ.JSFuncCall(\"customAlert\", \"Runs on page load\", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))\n\t<script>\n\t\tfunction onClickEventHandler(event, data) {\n\t\t\talert(event.type);\n\t\t\talert(data);\n\t\t\tevent.preventDefault();\n\t\t}\n\t</script>\n\t<button onclick={ templ.JSFuncCall(\"onClickEventHandler\", templ.JSExpression(\"event\"), \"1234\") }>Pass event handler</button>\n}\n"
  },
  {
    "path": "generator/test-js-usage/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testjsusage\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"time\"\n\nvar onceHandle = templ.NewOnceHandle()\n\nfunc TestComponent() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall(\"alert\", \"Hello, World!\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<button onClick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.ComponentScript = templ.JSFuncCall(\"alert\", \"Hello, World!\")\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">Click me</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<script>\\n\\t\\t\\tfunction customAlert(msg, date) {\\n\\t\\t\\t\\talert(msg + \\\" \\\" + date);\\n\\t\\t\\t}\\n\\t\\t</script>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = onceHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall(\"customAlert\", \"Hello, custom alert 1: \", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<button onClick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 templ.ComponentScript = templ.JSFuncCall(\"customAlert\", \"Hello, custom alert 1: \", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var4.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"\\\">Click me</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall(\"customAlert\", \"Hello, custom alert 2: \", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<button onClick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 templ.ComponentScript = templ.JSFuncCall(\"customAlert\", \"Hello, custom alert 2: \", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC))\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\">Click me</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.JSFuncCall(\"customAlert\", \"Runs on page load\", time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<script>\\n\\t\\tfunction onClickEventHandler(event, data) {\\n\\t\\t\\talert(event.type);\\n\\t\\t\\talert(data);\\n\\t\\t\\tevent.preventDefault();\\n\\t\\t}\\n\\t</script>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall(\"onClickEventHandler\", templ.JSExpression(\"event\"), \"1234\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"<button onclick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 templ.ComponentScript = templ.JSFuncCall(\"onClickEventHandler\", templ.JSExpression(\"event\"), \"1234\")\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"\\\">Pass event handler</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-method/expected.html",
    "content": "<div>You can implement methods on a type.</div>\n"
  },
  {
    "path": "generator/test-method/render_test.go",
    "content": "package testmethod\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\td := Data{\n\t\tmessage: \"You can implement methods on a type.\",\n\t}\n\tcomponent := d.Method()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-method/template.templ",
    "content": "package testmethod\n\ntype Data struct {\n\tmessage string\n}\n\ntempl (d Data) Method() {\n\t<div>{ d.message }</div>\n}\n"
  },
  {
    "path": "generator/test-method/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testmethod\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\ntype Data struct {\n\tmessage string\n}\n\nfunc (d Data) Method() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(d.message)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-method/template.templ`, Line: 8, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-once/expected.html",
    "content": "<script>\n\tfunction hello(name) {\n\t\talert(\"Hello, \" + name + \"!\");\n\t}\n</script>\n<input\n\ttype=\"button\"\n\tvalue=\"Hello User\"\n\tdata-name=\"user\"\n\tonclick=\"hello(this.getAttribute('data-name'))\"\n/><input\n\ttype=\"button\"\n\tvalue=\"Hello World\"\n\tdata-name=\"world\"\n\tonclick=\"hello(this.getAttribute('data-name'))\"\n/>\n"
  },
  {
    "path": "generator/test-once/render_test.go",
    "content": "package once\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-once/template.templ",
    "content": "package once\n\nvar helloHandle = templ.NewOnceHandle()\n\ntempl hello(label, name string) {\n\t@helloHandle.Once() {\n\t\t<script>\n\t\t\tfunction hello(name) {\n\t\t\t\talert(\"Hello, \" + name + \"!\");\n\t\t\t}\n\t\t</script>\n\t}\n\t<input type=\"button\" value={ label } data-name={ name } onclick=\"hello(this.getAttribute('data-name'))\"/>\n}\n\ntempl render() {\n\t@hello(\"Hello User\", \"user\")\n\t@hello(\"Hello World\", \"world\")\n}\n"
  },
  {
    "path": "generator/test-once/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage once\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nvar helloHandle = templ.NewOnceHandle()\n\nfunc hello(label, name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<script>\\n\\t\\t\\tfunction hello(name) {\\n\\t\\t\\t\\talert(\\\"Hello, \\\" + name + \\\"!\\\");\\n\\t\\t\\t}\\n\\t\\t</script>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = helloHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<input type=\\\"button\\\" value=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(label)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-once/template.templ`, Line: 13, Col: 35}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\" data-name=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-once/template.templ`, Line: 13, Col: 54}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\" onclick=\\\"hello(this.getAttribute('data-name'))\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc render() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = hello(\"Hello User\", \"user\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = hello(\"Hello World\", \"world\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-only-scripts/expected.html",
    "content": "<script>\n\tfunction __templ_withParameters_1056(a, b, c) {\n\t\tconsole.log(a, b, c);\n\t}\n</script>\n<script>\n\t__templ_withParameters_1056(\"hello\", \"world\", 42069);\n</script>\n"
  },
  {
    "path": "generator/test-only-scripts/render_test.go",
    "content": "package onlyscripts\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tscript := withParameters(\"hello\", \"world\", 42069)\n\n\tactual, diff, err := htmldiff.Diff(script, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-only-scripts/template.templ",
    "content": "package onlyscripts\n\nscript withParameters(a string, b string, c int) {\n\tconsole.log(a, b, c);\n}\n"
  },
  {
    "path": "generator/test-only-scripts/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage onlyscripts\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc withParameters(a string, b string, c int) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withParameters_1056`,\n\t\tFunction: `function __templ_withParameters_1056(a, b, c){console.log(a, b, c);\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withParameters_1056`, a, b, c),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withParameters_1056`, a, b, c),\n\t}\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-primitives/expected.html",
    "content": "<ul>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>1</li>\n\t<li>true</li>\n\t<li>false</li>\n\t<li>(10+11i)</li>\n\t<li>(10+11i)</li>\n\t<li>string value</li>\n\t<li>stringish value</li>\n</ul>\n"
  },
  {
    "path": "generator/test-primitives/render_test.go",
    "content": "package testprimitives\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-primitives/template.templ",
    "content": "package testprimitives\n\ntempl render() {\n\t<ul>\n\t\t<li>{ int(1) }</li>\n\t\t<li>{ int8(1) }</li>\n\t\t<li>{ int16(1) }</li>\n\t\t<li>{ int32(1) }</li>\n\t\t<li>{ int64(1) }</li>\n\t\t<li>{ uint(1) }</li>\n\t\t<li>{ uint8(1) }</li>\n\t\t<li>{ uint16(1) }</li>\n\t\t<li>{ uint32(1) }</li>\n\t\t<li>{ uint64(1) }</li>\n\t\t<li>{ float32(1) }</li>\n\t\t<li>{ float64(1) }</li>\n\t\t<li>{ true }</li>\n\t\t<li>{ false }</li>\n\t\t<li>{ complex64(10 + 11i) }</li>\n\t\t<li>{ complex128(10 + 11i) }</li>\n\t\t<li>{ \"string value\" }</li>\n\t\t<li>{ stringish(\"stringish value\") }</li>\n\t</ul>\n}\n\ntype stringish string\n"
  },
  {
    "path": "generator/test-primitives/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testprimitives\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<ul><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(int(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 5, Col: 14}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(int8(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 6, Col: 15}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(int16(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 7, Col: 16}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(int32(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 8, Col: 16}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 string\n\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(int64(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 9, Col: 16}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 string\n\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(uint(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 10, Col: 15}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var8 string\n\t\ttempl_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(uint8(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 11, Col: 16}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var9 string\n\t\ttempl_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(uint16(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 12, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var10 string\n\t\ttempl_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(uint32(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 13, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var11 string\n\t\ttempl_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(uint64(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 14, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var12 string\n\t\ttempl_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(float32(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 15, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var13 string\n\t\ttempl_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(float64(1))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 16, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var14 string\n\t\ttempl_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(true)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 17, Col: 12}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var15 string\n\t\ttempl_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(false)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 18, Col: 13}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var16 string\n\t\ttempl_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(complex64(10 + 11i))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 19, Col: 27}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var17 string\n\t\ttempl_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(complex128(10 + 11i))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 20, Col: 28}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var18 string\n\t\ttempl_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(\"string value\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 21, Col: 22}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var19 string\n\t\ttempl_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(stringish(\"stringish value\"))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-primitives/template.templ`, Line: 22, Col: 36}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, \"</li></ul>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\ntype stringish string\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-raw-elements/expected.html",
    "content": "<html>\n\t<head></head>\n\t<body>\n\t\t<style>\n\t\t\t<!-- Some stuff --></style\n\t\t><style>\n\t\t\t.customClass {\n\t\t\t\tborder: 1px solid black;\n\t\t\t}\n\t\t</style>\n\t\t<script>\n\t\t\t$(\"div\").marquee();\n\t\t\tfunction test() {\n\t\t\t\twindow.open(\"https://example.com\");\n\t\t\t}\n\t\t</script>\n\t\t<h1>Hello</h1>\n\t\t<div>World</div>\n\t</body>\n</html>\n"
  },
  {
    "path": "generator/test-raw-elements/render_test.go",
    "content": "package testrawelements\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := Example()\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-raw-elements/template.templ",
    "content": "package testrawelements\n\ntempl Example() {\n\t<html>\n\t\t<head></head>\n\t\t<body>\n\t\t\t<style>\n\t\t\t\t<!-- Some stuff -->\n\t\t\t</style>\n\t\t\t<style>\n\t\t\t\t.customClass {\n\t\t\t\t\tborder: 1px solid black;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<script>\n\t\t\t\t$(\"div\").marquee();\n\t\t\t\tfunction test() {\n\t\t\t\t\twindow.open(\"https://example.com\");\n\t\t\t\t}\n\t\t\t</script>\n\t\t\t<h1>Hello</h1>\n\t\t\t@templ.Raw(\"<div>World</div>\")\n\t\t</body>\n\t</html>\n}\n"
  },
  {
    "path": "generator/test-raw-elements/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testrawelements\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Example() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<html><head></head><body><style>\\n\\t\\t\\t\\t<!-- Some stuff -->\\n\\t\\t\\t</style><style>\\n\\t\\t\\t\\t.customClass {\\n\\t\\t\\t\\t\\tborder: 1px solid black;\\n\\t\\t\\t\\t}\\n\\t\\t\\t</style><script>\\n\\t\\t\\t\\t$(\\\"div\\\").marquee();\\n\\t\\t\\t\\tfunction test() {\\n\\t\\t\\t\\t\\twindow.open(\\\"https://example.com\\\");\\n\\t\\t\\t\\t}\\n\\t\\t\\t</script><h1>Hello</h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.Raw(\"<div>World</div>\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</body></html>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-script-expressions/expected.html",
    "content": "<h1>string data</h1>\n<script>\n\tvar a = \"hello\";\n\tvar b = \"hello\";\n\tvar c = \"hello\";\n\tvar d = `hello`;\n</script>\n<script>\n\tconsole.log(\"hello\");\n</script>\n<h1>string data with quotes</h1>\n<script>\n\tvar a = \"hello 'world'\";\n\tvar b = \"hello \\u0027world\\u0027\";\n\tvar c = \"hello \\u0027world\\u0027\";\n\tvar d = `hello \\u0027world\\u0027`;\n</script>\n<script>\n\tconsole.log(\"hello 'world'\");\n</script>\n<h1>numeric data</h1>\n<script>\n\tvar a = 123;\n\tvar b = \"123\";\n\tvar c = \"123\";\n\tvar d = `123`;\n</script>\n<script>\n\tconsole.log(123);\n</script>\n<h1>boolean data</h1>\n<script>\n\tvar a = true;\n\tvar b = \"true\";\n\tvar c = \"true\";\n\tvar d = `true`;\n</script>\n<script>\n\tconsole.log(true);\n</script>\n<h1>array data</h1>\n<script>\n\tvar a = [1, 2, 3];\n\tvar b = \"[1,2,3]\";\n\tvar c = \"[1,2,3]\";\n\tvar d = `[1,2,3]`;\n</script>\n<script>\n\tconsole.log([1, 2, 3]);\n</script>\n<h1>object data</h1>\n<script>\n\tvar a = { Name: \"Alice\", Age: 30 };\n\tvar b = \"{\\u0022Name\\u0022:\\u0022Alice\\u0022,\\u0022Age\\u0022:30}\";\n\tvar c = \"{\\u0022Name\\u0022:\\u0022Alice\\u0022,\\u0022Age\\u0022:30}\";\n\tvar d = `{\\u0022Name\\u0022:\\u0022Alice\\u0022,\\u0022Age\\u0022:30}`;\n</script>\n<script>\n\tconsole.log({ Name: \"Alice\", Age: 30 });\n</script>\n<h1>null data</h1>\n<script>\n\tvar a = null;\n\tvar b = \"null\";\n\tvar c = \"null\";\n\tvar d = `null`;\n</script>\n<script>\n\tconsole.log(null);\n</script>\n"
  },
  {
    "path": "generator/test-script-expressions/render_test.go",
    "content": "package testscriptexpressions\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := AllTests()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-script-expressions/template.templ",
    "content": "package testscriptexpressions\n\ntempl Script[T any](name string, data T) {\n\t<h1>{ name }</h1>\n\t<script>\n\t\tvar a = {{ data }}\n\t\tvar b = \"{{ data }}\"\n\t\tvar c = '{{ data }}'\n\t\tvar d = `{{ data }}`\n\t</script>\n\t<script>\n\t\tconsole.log({{ data }});\n\t</script>\n}\n\ntempl AllTests() {\n\t@Script(\"string data\", \"hello\")\n\t@Script(\"string data with quotes\", \"hello 'world'\")\n\t@Script(\"numeric data\", 123)\n\t@Script(\"boolean data\", true)\n\t@Script(\"array data\", []int{1, 2, 3})\n\t@Script(\"object data\", struct {\n\t\tName string\n\t\tAge  int\n\t}{\"Alice\", 30})\n\t@Script[*string](\"null data\", nil)\n}\n"
  },
  {
    "path": "generator/test-script-expressions/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testscriptexpressions\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Script[T any](name string, data T) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-expressions/template.templ`, Line: 4, Col: 11}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</h1><script>\\n\\t\\tvar a = \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err := templruntime.ScriptContentOutsideStringLiteral(data)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-expressions/template.templ`, Line: 6, Col: 17}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\n\\t\\tvar b = \\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err := templruntime.ScriptContentInsideStringLiteral(data)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-expressions/template.templ`, Line: 7, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var4)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\"\\n\\t\\tvar c = '\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err := templruntime.ScriptContentInsideStringLiteral(data)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-expressions/template.templ`, Line: 8, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"'\\n\\t\\tvar d = `\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err := templruntime.ScriptContentInsideStringLiteral(data)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-expressions/template.templ`, Line: 9, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"`\\n\\t</script><script>\\n\\t\\tconsole.log(\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err := templruntime.ScriptContentOutsideStringLiteral(data)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-expressions/template.templ`, Line: 12, Col: 21}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var7)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \");\\n\\t</script>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc AllTests() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var8 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var8 == nil {\n\t\t\ttempl_7745c5c3_Var8 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = Script(\"string data\", \"hello\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Script(\"string data with quotes\", \"hello 'world'\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Script(\"numeric data\", 123).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Script(\"boolean data\", true).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Script(\"array data\", []int{1, 2, 3}).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Script(\"object data\", struct {\n\t\t\tName string\n\t\t\tAge  int\n\t\t}{\"Alice\", 30}).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Script[*string](\"null data\", nil).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-script-inline/expected.html",
    "content": "<script>\n\tfunction __templ_withoutParameters_6bbf() {\n\t\talert(\"hello\");\n\t}\n</script>\n<script>\n\t__templ_withoutParameters_6bbf();\n</script>\n<script>\n\tfunction __templ_withParameters_1056(a, b, c) {\n\t\tconsole.log(a, b, c);\n\t}\n</script>\n<script>\n\t__templ_withParameters_1056(\"injected\", \"test\", 123);\n</script>\n<script>\n\t__templ_withoutParameters_6bbf();\n</script>\n<script>\n\t__templ_withParameters_1056(\"injected\", \"test\", 123);\n</script>\n"
  },
  {
    "path": "generator/test-script-inline/render_test.go",
    "content": "package testscriptinline\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := InlineJavascript(\"injected\")\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-script-inline/template.templ",
    "content": "package testscriptinline\n\nscript withParameters(a string, b string, c int) {\n\tconsole.log(a, b, c);\n}\n\nscript withoutParameters() {\n\talert(\"hello\");\n}\n\ntempl InlineJavascript(a string) {\n\t@withoutParameters()\n\t@withParameters(a, \"test\", 123)\n\t// Call once more, to ensure it's defined only once\n\t@withoutParameters()\n\t@withParameters(a, \"test\", 123)\n}\n"
  },
  {
    "path": "generator/test-script-inline/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testscriptinline\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc withParameters(a string, b string, c int) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withParameters_1056`,\n\t\tFunction: `function __templ_withParameters_1056(a, b, c){console.log(a, b, c);\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withParameters_1056`, a, b, c),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withParameters_1056`, a, b, c),\n\t}\n}\n\nfunc withoutParameters() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withoutParameters_6bbf`,\n\t\tFunction: `function __templ_withoutParameters_6bbf(){alert(\"hello\");\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withoutParameters_6bbf`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withoutParameters_6bbf`),\n\t}\n}\n\nfunc InlineJavascript(a string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = withoutParameters().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = withParameters(a, \"test\", 123).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = withoutParameters().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = withParameters(a, \"test\", 123).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-script-usage/expected.html",
    "content": "<script>\n\tfunction __templ_withParameters_1056(a, b, c) {\n\t\tconsole.log(a, b, c);\n\t}\n\tfunction __templ_withoutParameters_6bbf() {\n\t\talert(\"hello\");\n\t}\n</script>\n<button\n\tonClick=\"__templ_withParameters_1056(&#34;test&#34;,&#34;A&#34;,123)\"\n\tonMouseover=\"__templ_withoutParameters_6bbf()\"\n\ttype=\"button\"\n>\n\tA</button\n><button\n\tonClick=\"__templ_withParameters_1056(&#34;test&#34;,&#34;B&#34;,123)\"\n\tonMouseover=\"__templ_withoutParameters_6bbf()\"\n\ttype=\"button\"\n>\n\tB</button\n><button onMouseover=\"console.log('mouseover')\" type=\"button\">Button C</button>\n<button hx-on::click=\"alert('clicked inline')\" type=\"button\">Button D</button>\n<script>\n\tfunction __templ_onClick_657d() {\n\t\talert(\"clicked\");\n\t}\n</script>\n<button hx-on::click=\"__templ_onClick_657d()\" type=\"button\">Button E</button>\n<script>\n\tfunction __templ_whenButtonIsClicked_253e(event) {\n\t\tconsole.log(event.target);\n\t}\n</script>\n<button onclick=\"__templ_whenButtonIsClicked_253e(event)\">Button F</button>\n<script>\n\tfunction __templ_conditionalScript_de41() {\n\t\talert(\"conditional\");\n\t}\n</script>\n<input\n\ttype=\"button\"\n\tvalue=\"Click me\"\n\tonclick=\"__templ_conditionalScript_de41()\"\n/>\n<script>\n\tfunction __templ_alertTest_eadf() {\n\t\talert(\"testing\");\n\t}\n</script>\n<script\n\tasync\n\tcrossorigin=\"true\"\n\tonload=\"__templ_alertTest_eadf()\"\n\tsrc=\"url.to.some.script\"\n></script>\n"
  },
  {
    "path": "generator/test-script-usage/render_test.go",
    "content": "package testscriptusage\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := ThreeButtons()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-script-usage/template.templ",
    "content": "package testscriptusage\n\nscript withParameters(a string, b string, c int) {\n\tconsole.log(a, b, c);\n}\n\nscript withoutParameters() {\n\talert(\"hello\");\n}\n\nscript onClick() {\n\talert(\"clicked\");\n}\n\ntempl Button(text string) {\n\t<button onClick={ withParameters(\"test\", text, 123) } onMouseover={ withoutParameters() } type=\"button\">{ text }</button>\n}\n\nscript withComment() {\n\t//'\n}\n\nscript whenButtonIsClicked(event templ.JSExpression) {\n\tconsole.log(event.target)\n}\n\ntempl ThreeButtons() {\n\t@Button(\"A\")\n\t@Button(\"B\")\n\t<button onMouseover=\"console.log('mouseover')\" type=\"button\">Button C</button>\n\t<button hx-on::click=\"alert('clicked inline')\" type=\"button\">Button D</button>\n\t<button hx-on::click={ onClick() } type=\"button\">Button E</button>\n\t<button onclick={ whenButtonIsClicked(templ.JSExpression(\"event\")) }>Button F</button>\n\t@Conditional(true)\n\t@ScriptOnLoad()\n}\n\nscript conditionalScript() {\n  alert(\"conditional\");\n}\n\ntempl Conditional(show bool) {\n\t<input\n\t\ttype=\"button\"\n\t\tvalue=\"Click me\"\n\t\tif show {\n\t\t\tonclick={ conditionalScript() }\n\t\t}\n\t/>\n}\n\nscript alertTest() {\n\talert('testing');\n}\n\ntempl ScriptOnLoad() {\n\t<script async crossorigin=\"true\" onload={ alertTest() } src=\"url.to.some.script\"></script>\n}\n"
  },
  {
    "path": "generator/test-script-usage/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testscriptusage\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc withParameters(a string, b string, c int) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withParameters_1056`,\n\t\tFunction: `function __templ_withParameters_1056(a, b, c){console.log(a, b, c);\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withParameters_1056`, a, b, c),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withParameters_1056`, a, b, c),\n\t}\n}\n\nfunc withoutParameters() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withoutParameters_6bbf`,\n\t\tFunction: `function __templ_withoutParameters_6bbf(){alert(\"hello\");\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withoutParameters_6bbf`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withoutParameters_6bbf`),\n\t}\n}\n\nfunc onClick() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_onClick_657d`,\n\t\tFunction: `function __templ_onClick_657d(){alert(\"clicked\");\n}`,\n\t\tCall:       templ.SafeScript(`__templ_onClick_657d`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_onClick_657d`),\n\t}\n}\n\nfunc Button(text string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, withParameters(\"test\", text, 123), withoutParameters())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<button onClick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.ComponentScript = withParameters(\"test\", text, 123)\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\" onMouseover=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 templ.ComponentScript = withoutParameters()\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\" type=\\\"button\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(text)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-usage/template.templ`, Line: 16, Col: 111}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc withComment() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withComment_9cf8`,\n\t\tFunction: `function __templ_withComment_9cf8(){//'\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withComment_9cf8`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withComment_9cf8`),\n\t}\n}\n\nfunc whenButtonIsClicked(event templ.JSExpression) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_whenButtonIsClicked_253e`,\n\t\tFunction: `function __templ_whenButtonIsClicked_253e(event){console.log(event.target)\n}`,\n\t\tCall:       templ.SafeScript(`__templ_whenButtonIsClicked_253e`, event),\n\t\tCallInline: templ.SafeScriptInline(`__templ_whenButtonIsClicked_253e`, event),\n\t}\n}\n\nfunc ThreeButtons() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = Button(\"A\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Button(\"B\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<button onMouseover=\\\"console.log('mouseover')\\\" type=\\\"button\\\">Button C</button> <button hx-on::click=\\\"alert('clicked inline')\\\" type=\\\"button\\\">Button D</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, onClick())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<button hx-on::click=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 templ.ComponentScript = onClick()\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\" type=\\\"button\\\">Button E</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, whenButtonIsClicked(templ.JSExpression(\"event\")))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<button onclick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 templ.ComponentScript = whenButtonIsClicked(templ.JSExpression(\"event\"))\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var7.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"\\\">Button F</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Conditional(true).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = ScriptOnLoad().Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc conditionalScript() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_conditionalScript_de41`,\n\t\tFunction: `function __templ_conditionalScript_de41(){alert(\"conditional\");\n}`,\n\t\tCall:       templ.SafeScript(`__templ_conditionalScript_de41`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_conditionalScript_de41`),\n\t}\n}\n\nfunc Conditional(show bool) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var8 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var8 == nil {\n\t\t\ttempl_7745c5c3_Var8 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, conditionalScript())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"<input type=\\\"button\\\" value=\\\"Click me\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif show {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \" onclick=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var9 templ.ComponentScript = conditionalScript()\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var9.Call)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc alertTest() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_alertTest_eadf`,\n\t\tFunction: `function __templ_alertTest_eadf(){alert('testing');\n}`,\n\t\tCall:       templ.SafeScript(`__templ_alertTest_eadf`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_alertTest_eadf`),\n\t}\n}\n\nfunc ScriptOnLoad() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var10 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var10 == nil {\n\t\t\ttempl_7745c5c3_Var10 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, alertTest())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, \"<script async crossorigin=\\\"true\\\" onload=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var11 templ.ComponentScript = alertTest()\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var11.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, \"\\\" src=\\\"url.to.some.script\\\"></script>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-script-usage-nonce/expected.html",
    "content": "<script nonce=\"nonce1\">\n\tfunction __templ_withParameters_1056(a, b, c) {\n\t\tconsole.log(a, b, c);\n\t}\n\tfunction __templ_withoutParameters_6bbf() {\n\t\talert(\"hello\");\n\t}\n</script>\n<button\n\tonClick=\"__templ_withParameters_1056(&#34;test&#34;,&#34;A&#34;,123)\"\n\tonMouseover=\"__templ_withoutParameters_6bbf()\"\n\ttype=\"button\"\n>\n\tA</button\n><button\n\tonClick=\"__templ_withParameters_1056(&#34;test&#34;,&#34;B&#34;,123)\"\n\tonMouseover=\"__templ_withoutParameters_6bbf()\"\n\ttype=\"button\"\n>\n\tB</button\n><button onMouseover=\"console.log('mouseover')\" type=\"button\">Button C</button>\n<button hx-on::click=\"alert('clicked inline')\" type=\"button\">Button D</button>\n<script nonce=\"nonce1\">\n\tfunction __templ_onClick_657d() {\n\t\talert(\"clicked\");\n\t}\n</script>\n<button hx-on::click=\"__templ_onClick_657d()\" type=\"button\">Button E</button>\n<script nonce=\"nonce1\">\n\tfunction __templ_conditionalScript_de41() {\n\t\talert(\"conditional\");\n\t}\n</script>\n<input\n\ttype=\"button\"\n\tvalue=\"Click me\"\n\tonclick=\"__templ_conditionalScript_de41()\"\n/>\n"
  },
  {
    "path": "generator/test-script-usage-nonce/render_test.go",
    "content": "package testscriptusage\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := ThreeButtons()\n\n\tctx := templ.WithNonce(context.Background(), \"nonce1\")\n\t_, diff, err := htmldiff.DiffCtx(ctx, component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-script-usage-nonce/template.templ",
    "content": "package testscriptusage\n\nscript withParameters(a string, b string, c int) {\n\tconsole.log(a, b, c);\n}\n\nscript withoutParameters() {\n\talert(\"hello\");\n}\n\nscript onClick() {\n\talert(\"clicked\");\n}\n\ntempl Button(text string) {\n\t<button onClick={ withParameters(\"test\", text, 123) } onMouseover={ withoutParameters() } type=\"button\">{ text }</button>\n}\n\nscript withComment() {\n\t//'\n}\n\ntempl ThreeButtons() {\n\t@Button(\"A\")\n\t@Button(\"B\")\n\t<button onMouseover=\"console.log('mouseover')\" type=\"button\">Button C</button>\n\t<button hx-on::click=\"alert('clicked inline')\" type=\"button\">Button D</button>\n\t<button hx-on::click={ onClick() } type=\"button\">Button E</button>\n\t@Conditional(true)\n}\n\nscript conditionalScript() {\n  alert(\"conditional\");\n}\n\ntempl Conditional(show bool) {\n\t<input\n\t\ttype=\"button\"\n\t\tvalue=\"Click me\"\n\t\tif show {\n\t\t\tonclick={ conditionalScript() }\n\t\t}\n\t/>\n}\n"
  },
  {
    "path": "generator/test-script-usage-nonce/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testscriptusage\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc withParameters(a string, b string, c int) templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withParameters_1056`,\n\t\tFunction: `function __templ_withParameters_1056(a, b, c){console.log(a, b, c);\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withParameters_1056`, a, b, c),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withParameters_1056`, a, b, c),\n\t}\n}\n\nfunc withoutParameters() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withoutParameters_6bbf`,\n\t\tFunction: `function __templ_withoutParameters_6bbf(){alert(\"hello\");\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withoutParameters_6bbf`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withoutParameters_6bbf`),\n\t}\n}\n\nfunc onClick() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_onClick_657d`,\n\t\tFunction: `function __templ_onClick_657d(){alert(\"clicked\");\n}`,\n\t\tCall:       templ.SafeScript(`__templ_onClick_657d`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_onClick_657d`),\n\t}\n}\n\nfunc Button(text string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, withParameters(\"test\", text, 123), withoutParameters())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<button onClick=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 templ.ComponentScript = withParameters(\"test\", text, 123)\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\" onMouseover=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 templ.ComponentScript = withoutParameters()\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\" type=\\\"button\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(text)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-script-usage-nonce/template.templ`, Line: 16, Col: 111}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc withComment() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_withComment_9cf8`,\n\t\tFunction: `function __templ_withComment_9cf8(){//'\n}`,\n\t\tCall:       templ.SafeScript(`__templ_withComment_9cf8`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_withComment_9cf8`),\n\t}\n}\n\nfunc ThreeButtons() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = Button(\"A\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Button(\"B\").Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<button onMouseover=\\\"console.log('mouseover')\\\" type=\\\"button\\\">Button C</button> <button hx-on::click=\\\"alert('clicked inline')\\\" type=\\\"button\\\">Button D</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, onClick())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<button hx-on::click=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 templ.ComponentScript = onClick()\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6.Call)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\" type=\\\"button\\\">Button E</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = Conditional(true).Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc conditionalScript() templ.ComponentScript {\n\treturn templ.ComponentScript{\n\t\tName: `__templ_conditionalScript_de41`,\n\t\tFunction: `function __templ_conditionalScript_de41(){alert(\"conditional\");\n}`,\n\t\tCall:       templ.SafeScript(`__templ_conditionalScript_de41`),\n\t\tCallInline: templ.SafeScriptInline(`__templ_conditionalScript_de41`),\n\t}\n}\n\nfunc Conditional(show bool) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var7 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var7 == nil {\n\t\t\ttempl_7745c5c3_Var7 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, conditionalScript())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<input type=\\\"button\\\" value=\\\"Click me\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif show {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \" onclick=\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var8 templ.ComponentScript = conditionalScript()\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var8.Call)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"\\\"\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-spread-attributes/expected.html",
    "content": "<div>\n  <a\n    bool\n    data-attr=\"value\"\n    data-attr-bool\n    dateId=\"my-custom-id\"\n    hx-get=\"/page\"\n    id=\"test\"\n    nonshade\n    optional-from-func-true\n    text=\"lorem\"\n  >text</a>\n  <div\n    bool\n    data-attr=\"value\"\n    data-attr-bool\n    dateId=\"my-custom-id\"\n    hx-get=\"/page\"\n    id=\"test\"\n    nonshade\n    optional-from-func-true\n    text=\"lorem\"\n  >text2</div>\n  <div>text3</div>\n</div>\n"
  },
  {
    "path": "generator/test-spread-attributes/expected_numeric_attributes.html",
    "content": "<div>\n\t<a\n\t\tbool-true\n\t\tcomplex-value=\"(1+2i)\"\n\t\tfloat-value=\"3.14\"\n\t\tint-value=\"42\"\n\t\tint64-value=\"9223372036854775807\"\n\t\tstring-value=\"text\"\n\t\tuint-value=\"100\"\n\t\t>text</a\n\t>\n\t<div\n\t\tbool-true\n\t\tcomplex-value=\"(1+2i)\"\n\t\tfloat-value=\"3.14\"\n\t\tint-value=\"42\"\n\t\tint64-value=\"9223372036854775807\"\n\t\tstring-value=\"text\"\n\t\tuint-value=\"100\"\n\t>\n\t\ttext2\n\t</div>\n\t<div>text3</div>\n</div>\n"
  },
  {
    "path": "generator/test-spread-attributes/expected_ordered_attributes.html",
    "content": "<div>\n\t<a\n\t\tbool\n\t\tdata-attr=\"value\"\n\t\tdata-attr-bool\n\t\tdateId=\"my-custom-id\"\n\t\thx-get=\"/page\"\n\t\tid=\"test\"\n\t\tnonshade\n\t\ttext=\"lorem\"\n\t\toptional-from-func-true\n\t\t>text</a\n\t>\n\t<div\n\t\tbool\n\t\tdata-attr=\"value\"\n\t\tdata-attr-bool\n\t\tdateId=\"my-custom-id\"\n\t\thx-get=\"/page\"\n\t\tid=\"test\"\n\t\tnonshade\n\t\ttext=\"lorem\"\n\t\toptional-from-func-true\n\t>\n\t\ttext2\n\t</div>\n\t<div>text3</div>\n</div>\n"
  },
  {
    "path": "generator/test-spread-attributes/render_test.go",
    "content": "package testspreadattributes\n\nimport (\n\t_ \"embed\"\n\t\"testing\"\n\n\t\"os\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := BasicTemplate(templ.Attributes{\n\t\t// Should render as `bool` as the value is true, and the conditional render is also true.\n\t\t\"bool\": templ.KV(true, true),\n\t\t// Should not render, as the conditional render value is false.\n\t\t\"bool-disabled\": templ.KV(true, false),\n\t\t// Should render non-nil string values.\n\t\t\"data-attr\": ptr(\"value\"),\n\t\t// Should render non-nil boolean values that evaluate to true.\n\t\t\"data-attr-bool\": ptr(true),\n\t\t// Should render as `dateId=\"my-custom-id\"`.\n\t\t\"dateId\": \"my-custom-id\",\n\t\t// Should render as `hx-get=\"/page\"`.\n\t\t\"hx-get\": \"/page\",\n\t\t// Should render as `id=\"test\"`.\n\t\t\"id\": \"test\",\n\t\t// Should not render a nil string pointer.\n\t\t\"key\": nilPtr[string](),\n\t\t// Should not render a nil boolean value.\n\t\t\"boolkey\": nilPtr[bool](),\n\t\t// Should not render, as the attribute value, and the conditional render value is false.\n\t\t\"no-bool\": templ.KV(false, false),\n\t\t// Should not render, as the conditional render value is false.\n\t\t\"no-text\": templ.KV(\"empty\", false),\n\t\t// Should render as `nonshare`, as the value is true.\n\t\t\"nonshade\": true,\n\t\t// Should not render, as the value is false.\n\t\t\"shade\": false,\n\t\t// Should render text=\"lorem\" as the value is true.\n\t\t\"text\": templ.KV(\"lorem\", true),\n\t\t// Optional attribute based on result of func() bool.\n\t\t\"optional-from-func-false\": func() bool { return false },\n\t\t// Optional attribute based on result of func() bool.\n\t\t\"optional-from-func-true\": func() bool { return true },\n\t})\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n\n//go:embed expected_ordered_attributes.html\nvar expectedOrderedAttributes string\n\nfunc TestOrderedAttributes(t *testing.T) {\n\tcomponent := BasicTemplateOrdered(templ.OrderedAttributes{\n\t\t// Should render as `bool` as the value is true, and the conditional render is also true.\n\t\t{Key: \"bool\", Value: templ.KV(true, true)},\n\t\t// Should not render, as the conditional render value is false.\n\t\t{Key: \"bool-disabled\", Value: templ.KV(true, false)},\n\t\t// Should render non-nil string values.\n\t\t{Key: \"data-attr\", Value: ptr(\"value\")},\n\t\t// Should render non-nil boolean values that evaluate to true.\n\t\t{Key: \"data-attr-bool\", Value: ptr(true)},\n\t\t// Should render as `dateId=\"my-custom-id\"`.\n\t\t{Key: \"dateId\", Value: \"my-custom-id\"},\n\t\t// Should render as `hx-get=\"/page\"`.\n\t\t{Key: \"hx-get\", Value: \"/page\"},\n\t\t// Should render as `id=\"test\"`.\n\t\t{Key: \"id\", Value: \"test\"},\n\t\t// Should not render a nil string pointer.\n\t\t{Key: \"key\", Value: nilPtr[string]()},\n\t\t// Should not render a nil boolean value.\n\t\t{Key: \"boolkey\", Value: nilPtr[bool]()},\n\t\t// Should not render, as the attribute value, and the conditional render value is false.\n\t\t{Key: \"no-bool\", Value: templ.KV(false, false)},\n\t\t// Should not render, as the conditional render value is false.\n\t\t{Key: \"no-text\", Value: templ.KV(\"empty\", false)},\n\t\t// Should render as `nonshare`, as the value is true.\n\t\t{Key: \"nonshade\", Value: true},\n\t\t// Should not render, as the value is false.\n\t\t{Key: \"shade\", Value: false},\n\t\t// Should render text=\"lorem\" as the value is true.\n\t\t{Key: \"text\", Value: templ.KV(\"lorem\", true)},\n\t\t// Optional attribute based on result of func() bool.\n\t\t{Key: \"optional-from-func-false\", Value: func() bool { return false }},\n\t\t// Optional attribute based on result of func() bool.\n\t\t{Key: \"optional-from-func-true\", Value: func() bool { return true }},\n\t})\n\n\tactual, diff, err := htmldiff.Diff(component, expectedOrderedAttributes)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n\nfunc nilPtr[T any]() *T {\n\treturn nil\n}\n\nfunc ptr[T any](x T) *T {\n\treturn &x\n}\n\n//go:embed expected_numeric_attributes.html\nvar expectedNumericAttributes string\n\nfunc TestNumericAttributeTypes(t *testing.T) {\n\tt.Parallel()\n\tcomponent := BasicTemplate(templ.Attributes{\n\t\t\"int-value\":     42,\n\t\t\"float-value\":   3.14,\n\t\t\"uint-value\":    uint(100),\n\t\t\"int64-value\":   int64(9223372036854775807),\n\t\t\"complex-value\": complex(1, 2),\n\t\t\"string-value\":  \"text\",\n\t\t\"bool-true\":     true,\n\t\t\"bool-false\":    false,\n\t})\n\n\tactual, diff, err := htmldiff.Diff(component, expectedNumericAttributes)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-spread-attributes/template.templ",
    "content": "package testspreadattributes\n\ntempl BasicTemplate(spread templ.Attributes) {\n\t<div>\n\t\t<a { spread... }>text</a>\n\t\t<div\n\t\t\tif true {\n\t\t\t\t{ spread... }\n\t\t\t}\n\t\t>text2</div>\n\t\t<div\n\t\t\tif false {\n\t\t\t\t{ spread... }\n\t\t\t}\n\t\t>text3</div>\n\t</div>\n}\n\ntempl BasicTemplateOrdered(spread templ.OrderedAttributes) {\n\t<div>\n\t\t<a { spread... }>text</a>\n\t\t<div\n\t\t\tif true {\n\t\t\t\t{ spread... }\n\t\t\t}\n\t\t>text2</div>\n\t\t<div\n\t\t\tif false {\n\t\t\t\t{ spread... }\n\t\t\t}\n\t\t>text3</div>\n\t</div>\n}\n"
  },
  {
    "path": "generator/test-spread-attributes/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testspreadattributes\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc BasicTemplate(spread templ.Attributes) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div><a\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, spread)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \">text</a><div\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\ttempl_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, spread)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \">text2</div><div\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif false {\n\t\t\ttempl_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, spread)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \">text3</div></div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc BasicTemplateOrdered(spread templ.OrderedAttributes) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var2 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var2 == nil {\n\t\t\ttempl_7745c5c3_Var2 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<div><a\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, spread)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \">text</a><div\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\ttempl_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, spread)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \">text2</div><div\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif false {\n\t\t\ttempl_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, spread)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \">text3</div></div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-string/expected.html",
    "content": "<ul>\n\t<li></li>\n\t<li>\n\t\tStrings are HTML escaped. So ampersands (&amp;), greater than (&gt;), and\n\t\tless than symbols (&lt;) are converted.\n\t</li>\n\t<li>Spaces are preserved.</li>\n</ul>\n"
  },
  {
    "path": "generator/test-string/render_test.go",
    "content": "package teststring\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render(`Strings are HTML escaped. So ampersands (&), greater than (>), and less than symbols (<) are converted.`)\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-string/template.templ",
    "content": "package teststring\n\ntempl render(s string) {\n\t<ul>\n\t\t<li>{  }</li>\n\t\t<li>{ s }</li>\n\t\t<li>{ \"Spaces\" } { \"are\" } { \"preserved.\" }</li>\n\t</ul>\n}\n"
  },
  {
    "path": "generator/test-string/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage teststring\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(s string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<ul><li></li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(s)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-string/template.templ`, Line: 6, Col: 9}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(\"Spaces\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-string/template.templ`, Line: 7, Col: 16}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \" \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(\"are\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-string/template.templ`, Line: 7, Col: 26}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \" \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(\"preserved.\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-string/template.templ`, Line: 7, Col: 43}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</li></ul>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-string-errors/expected.html",
    "content": "<ul>\n\t<li>raw</li>\n\t<li>OK</li>\n\t<li>OK2</li>\n</ul>\n"
  },
  {
    "path": "generator/test-string-errors/render_test.go",
    "content": "package teststringerrs\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t_ \"embed\"\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tt.Run(\"can render without error\", func(t *testing.T) {\n\t\tcomponent := TestComponent(nil)\n\n\t\t_, _, err := htmldiff.Diff(component, expected)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"string expressions can return errors\", func(t *testing.T) {\n\t\terrSomethingBad := errors.New(\"bad error\")\n\n\t\terr := TestComponent(errSomethingBad).Render(context.Background(), &bytes.Buffer{})\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"expected error, but got nil\")\n\t\t}\n\n\t\tt.Run(\"the errors are templ errors\", func(t *testing.T) {\n\t\t\tvar templateErr templ.Error\n\t\t\tif !errors.As(err, &templateErr) {\n\t\t\t\tt.Fatalf(\"expected error to be templ.Error, but got %T\", err)\n\t\t\t}\n\t\t\tif templateErr.FileName != `generator/test-string-errors/template.templ` {\n\t\t\t\tt.Errorf(\"expected error in `generator/test-string-errors/template.templ`, but got %v\", templateErr.FileName)\n\t\t\t}\n\t\t\tif templateErr.Line != 18 {\n\t\t\t\tt.Errorf(\"expected error on line 18, but got %v\", templateErr.Line)\n\t\t\t}\n\t\t\tif templateErr.Col != 26 {\n\t\t\t\tt.Errorf(\"expected error on column 26, but got %v\", templateErr.Col)\n\t\t\t}\n\t\t})\n\n\t\tt.Run(\"the underlying error can be unwrapped\", func(t *testing.T) {\n\t\t\tif !errors.Is(err, errSomethingBad) {\n\t\t\t\tt.Errorf(\"expected error: %v, but got %v\", errSomethingBad, err)\n\t\t\t}\n\t\t})\n\n\t})\n}\n"
  },
  {
    "path": "generator/test-string-errors/template.templ",
    "content": "package teststringerrs\n\nfunc funcWithNoError() (s string) {\n\treturn \"OK\"\n}\n\nfunc funcWithError(in error) (s string, err error) {\n\tif in != nil {\n\t\treturn \"\", in\n\t}\n\treturn \"OK2\", nil\n}\n\ntempl TestComponent(err error) {\n\t<ul>\n\t\t<li>{ \"raw\" }</li>\n\t\t<li>{ funcWithNoError() }</li>\n\t\t<li>{ funcWithError(err) }</li>\n\t</ul>\n}\n"
  },
  {
    "path": "generator/test-string-errors/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage teststringerrs\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc funcWithNoError() (s string) {\n\treturn \"OK\"\n}\n\nfunc funcWithError(in error) (s string, err error) {\n\tif in != nil {\n\t\treturn \"\", in\n\t}\n\treturn \"OK2\", nil\n}\n\nfunc TestComponent(err error) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<ul><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(\"raw\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-string-errors/template.templ`, Line: 16, Col: 13}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(funcWithNoError())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-string-errors/template.templ`, Line: 17, Col: 25}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</li><li>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(funcWithError(err))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-string-errors/template.templ`, Line: 18, Col: 26}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</li></ul>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-style-attribute/expected.html",
    "content": "<button style=\"background-color: blue; color: red\">Click me</button>\n<button style=\"background-color: red\">Click me</button>\n"
  },
  {
    "path": "generator/test-style-attribute/render_test.go",
    "content": "package teststyleattribute\n\nimport (\n\t_ \"embed\"\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tvar stringCSS = \"background-color:blue;color:red\"\n\tvar safeCSS = templ.SafeCSS(\"background-color:blue;color:red;\")\n\tvar mapStringString = map[string]string{\n\t\t\"color\":            \"red\",\n\t\t\"background-color\": \"blue\",\n\t}\n\tvar mapStringSafeCSSProperty = map[string]templ.SafeCSSProperty{\n\t\t\"color\":            templ.SafeCSSProperty(\"red\"),\n\t\t\"background-color\": templ.SafeCSSProperty(\"blue\"),\n\t}\n\tvar kvStringStringSlice = []templ.KeyValue[string, string]{\n\t\ttempl.KV(\"background-color\", \"blue\"),\n\t\ttempl.KV(\"color\", \"red\"),\n\t}\n\tvar kvStringBoolSlice = []templ.KeyValue[string, bool]{\n\t\ttempl.KV(\"background-color:blue\", true),\n\t\ttempl.KV(\"color:red\", true),\n\t\ttempl.KV(\"color:blue\", false),\n\t}\n\tvar kvSafeCSSBoolSlice = []templ.KeyValue[templ.SafeCSS, bool]{\n\t\ttempl.KV(templ.SafeCSS(\"background-color:blue\"), true),\n\t\ttempl.KV(templ.SafeCSS(\"color:red\"), true),\n\t\ttempl.KV(templ.SafeCSS(\"color:blue\"), false),\n\t}\n\n\ttests := []any{\n\t\tstringCSS,\n\t\tsafeCSS,\n\t\tmapStringString,\n\t\tmapStringSafeCSSProperty,\n\t\tkvStringStringSlice,\n\t\tkvStringBoolSlice,\n\t\tkvSafeCSSBoolSlice,\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(fmt.Sprintf(\"%T\", test), func(t *testing.T) {\n\t\t\tcomponent := Button(test, \"Click me\")\n\n\t\t\tactual, diff, err := htmldiff.Diff(component, expected)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif diff != \"\" {\n\t\t\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t\t\t}\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "generator/test-style-attribute/template.templ",
    "content": "package teststyleattribute\n\ntempl Button[T any](style T, text string) {\n\t<button style={ style }>{ text }</button>\n\t<button style={ getFunctionResult() }>{ text }</button>\n}\n\nfunc getFunctionResult() (string, error) {\n\treturn \"background-color: red\", nil\n}\n"
  },
  {
    "path": "generator/test-style-attribute/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage teststyleattribute\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc Button[T any](style T, text string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<button style=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues(style)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-style-attribute/template.templ`, Line: 4, Col: 22}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(text)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-style-attribute/template.templ`, Line: 4, Col: 31}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</button> <button style=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues(getFunctionResult())\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-style-attribute/template.templ`, Line: 5, Col: 36}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(text)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-style-attribute/template.templ`, Line: 5, Col: 45}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc getFunctionResult() (string, error) {\n\treturn \"background-color: red\", nil\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-switch/render_test.go",
    "content": "package testswitch\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nvar input = \"a\"\n\nconst expected = `it was &#39;a&#39;`\n\nfunc TestRender(t *testing.T) {\n\tw := new(strings.Builder)\n\terr := render(input).Render(context.Background(), w)\n\tif err != nil {\n\t\tt.Errorf(\"failed to render: %v\", err)\n\t}\n\tif diff := cmp.Diff(expected, w.String()); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-switch/template.templ",
    "content": "package testswitch\n\ntempl render(input string) {\n\tswitch input {\n\t\tcase \"a\":\n\t\t\t{ \"it was 'a'\" }\n\t\tdefault:\n\t\t\t{ \"it was something else\" }\n\t}\n}\n"
  },
  {
    "path": "generator/test-switch/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testswitch\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render(input string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tswitch input {\n\t\tcase \"a\":\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(\"it was 'a'\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-switch/template.templ`, Line: 6, Col: 17}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\tdefault:\n\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(\"it was something else\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-switch/template.templ`, Line: 8, Col: 28}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-switchdefault/render_test.go",
    "content": "package testswitchdefault\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nvar input = \"b\"\n\nconst expected = `it was something else`\n\nfunc TestRender(t *testing.T) {\n\tw := new(strings.Builder)\n\terr := template(input).Render(context.Background(), w)\n\tif err != nil {\n\t\tt.Errorf(\"failed to render: %v\", err)\n\t}\n\tif diff := cmp.Diff(expected, w.String()); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-switchdefault/template.templ",
    "content": "package testswitchdefault\n\ntempl template(input string) {\n\tswitch input {\n\t\tcase \"a\":\n\t\t\t{ \"it was 'a'\" }\n\t\tdefault:\n\t\t\t{ \"it was something else\" }\n\t}\n}\n"
  },
  {
    "path": "generator/test-switchdefault/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testswitchdefault\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc template(input string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\tswitch input {\n\t\tcase \"a\":\n\t\t\tvar templ_7745c5c3_Var2 string\n\t\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(\"it was 'a'\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-switchdefault/template.templ`, Line: 6, Col: 17}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\tdefault:\n\t\t\tvar templ_7745c5c3_Var3 string\n\t\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(\"it was something else\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-switchdefault/template.templ`, Line: 8, Col: 28}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-templ-element/expected.html",
    "content": "<div id=\"1\">\n\tchild1\n\t<div id=\"2\">\n\t\tchild2\n\t\t<div id=\"3\">\n\t\t\tchild3\n\t\t\t<div id=\"4\"></div>\n\t\t</div>\n\t</div>\n</div>\n"
  },
  {
    "path": "generator/test-templ-element/render_test.go",
    "content": "package testtemplelement\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t_ \"embed\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := template()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-templ-element/template.templ",
    "content": "package testtemplelement\n\nimport \"fmt\"\n\ntempl wrapper(index int) {\n\t<div id={ fmt.Sprint(index) }>\n\t\t{ children... }\n\t</div>\n}\n\ntempl template() {\n\t@wrapper(1) {\n\t\tchild1\n\t\t@wrapper(2) {\n\t\t\tchild2\n\t\t\t@wrapper(3) {\n\t\t\t\tchild3\n\t\t\t\t@wrapper(4)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "generator/test-templ-element/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testtemplelement\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"fmt\"\n\nfunc wrapper(index int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div id=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(index))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-templ-element/template.templ`, Line: 6, Col: 28}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\">\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc template() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\tdefer func() {\n\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"child1\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t}\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"child2\")\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\ttempl_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\t\t\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\t\t\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\t\t\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\t\t\t\tdefer func() {\n\t\t\t\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}()\n\t\t\t\t\t}\n\t\t\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"child3\")\n\t\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t\t}\n\t\t\t\t\ttempl_7745c5c3_Err = wrapper(4).Render(ctx, templ_7745c5c3_Buffer)\n\t\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t\ttempl_7745c5c3_Err = wrapper(3).Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\ttempl_7745c5c3_Err = wrapper(2).Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\ttempl_7745c5c3_Err = wrapper(1).Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-templ-in-go-template/expected.html",
    "content": "<!doctype html>\n<html>\n\t<body>\n\t\t<div>Hello, World!</div>\n\t</body>\n</html>\n"
  },
  {
    "path": "generator/test-templ-in-go-template/render_test.go",
    "content": "package testgotemplates\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc TestExample(t *testing.T) {\n\t// Create the templ component.\n\ttemplComponent := greeting()\n\thtml, err := templ.ToGoHTML(context.Background(), templComponent)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to convert to html: %v\", err)\n\t}\n\n\t// Use it within the text/html template.\n\tb := new(strings.Builder)\n\terr = example.Execute(b, html)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to execute template: %v\", err)\n\t}\n\n\t// Compare the output with the expected.\n\tactual, diff, err := htmldiff.DiffStrings(expected, b.String())\n\tif err != nil {\n\t\tt.Fatalf(\"failed to diff strings: %v\", err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-templ-in-go-template/template.templ",
    "content": "package testgotemplates\n\nimport \"html/template\"\n\nvar example = template.Must(template.New(\"example\").Parse(`<!DOCTYPE html>\n<html>\n\t<body>\n\t\t{{ . }}\n\t</body>\n</html>\n`))\n\ntempl greeting() {\n\t<div>Hello, World!</div>\n}\n"
  },
  {
    "path": "generator/test-templ-in-go-template/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testgotemplates\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"html/template\"\n\nvar example = template.Must(template.New(\"example\").Parse(`<!DOCTYPE html>\n<html>\n\t<body>\n\t\t{{ . }}\n\t</body>\n</html>\n`))\n\nfunc greeting() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Hello, World!</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-text/expected.html",
    "content": "<div>Name: Luiz Bonfa</div>\n<div>Text `with backticks`</div>\n<div>Text `with backtick</div>\n<div>Text `with backtick alongside variable: Luiz Bonfa</div>\n"
  },
  {
    "path": "generator/test-text/render_test.go",
    "content": "package testtext\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t_ \"embed\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := BasicTemplate(\"Luiz Bonfa\")\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-text/template.templ",
    "content": "package testtext\n\ntempl BasicTemplate(name string) {\n\t<div>Name: { name }</div>\n\t<div>Text `with backticks`</div>\n\t<div>Text `with backtick</div>\n\t<div>Text `with backtick alongside variable: { name }</div>\n}\n"
  },
  {
    "path": "generator/test-text/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testtext\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc BasicTemplate(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<div>Name: \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-text/template.templ`, Line: 4, Col: 18}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"</div><div>Text `with backticks`</div><div>Text `with backtick</div><div>Text `with backtick alongside variable: \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-text/template.templ`, Line: 7, Col: 52}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-text-whitespace/render_test.go",
    "content": "package testtextwhitespace\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestTextWhitespace(t *testing.T) {\n\tfor _, test := range []struct {\n\t\tname     string\n\t\tinput    templ.Component\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"whitespace is added within templ statements\",\n\t\t\tinput:    WhitespaceIsAddedWithinTemplStatements(),\n\t\t\texpected: WhitespaceIsAddedWithinTemplStatementsExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"inline elements are not padded\",\n\t\t\tinput:    InlineElementsAreNotPadded(),\n\t\t\texpected: InlineElementsAreNotPaddedExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace in HTML is normalised\",\n\t\t\tinput:    WhiteSpaceInHTMLIsNormalised(),\n\t\t\texpected: WhiteSpaceInHTMLIsNormalisedExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace around values is maintained\",\n\t\t\tinput:    WhiteSpaceAroundValues(),\n\t\t\texpected: WhiteSpaceAroundValuesExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace around templated values is maintained\",\n\t\t\tinput:    WhiteSpaceAroundTemplatedValues(\"templ\", \"allows whitespace around templated values.\"),\n\t\t\texpected: WhiteSpaceAroundTemplatedValuesExpected,\n\t\t},\n\t} {\n\t\tw := new(strings.Builder)\n\t\terr := test.input.Render(context.Background(), w)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"failed to render: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(test.expected, w.String()); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "generator/test-text-whitespace/template.templ",
    "content": "package testtextwhitespace\n\ntempl WhitespaceIsAddedWithinTemplStatements() {\n\t<p>\n\t\tThis is some text.\n\t\tif true {\n\t\t\tSo is this.\n\t\t}\n\t</p>\n}\n\nconst WhitespaceIsAddedWithinTemplStatementsExpected = `<p>This is some text. So is this.</p>`\n\ntempl InlineElementsAreNotPadded() {\n\t<p>Inline text <b>is spaced properly</b> without adding extra spaces.</p>\n}\n\nconst InlineElementsAreNotPaddedExpected = `<p>Inline text <b>is spaced properly</b> without adding extra spaces.</p>`\n\ntempl WhiteSpaceInHTMLIsNormalised() {\n\t<p>\n\t\tnewlines and other whitespace are stripped\n\t\tbut it is normalised\n\t\tlike HTML.\n\t</p>\n}\n\nconst WhiteSpaceInHTMLIsNormalisedExpected = `<p>newlines and other whitespace are stripped but it is normalised like HTML.</p>`\n\ntempl WhiteSpaceAroundValues() {\n\t<p>templ allows { \"strings\" } to be included in sentences.</p>\n}\n\nconst WhiteSpaceAroundValuesExpected = `<p>templ allows strings to be included in sentences.</p>`\n\nconst WhiteSpaceAroundTemplatedValuesExpected = `<div>templ allows whitespace around templated values.</div>`\n\ntempl WhiteSpaceAroundTemplatedValues(prefix, statement string) {\n\t<div>{ prefix } { statement }</div>\n}\n"
  },
  {
    "path": "generator/test-text-whitespace/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testtextwhitespace\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc WhitespaceIsAddedWithinTemplStatements() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<p>This is some text. \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif true {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"So is this.\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"</p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhitespaceIsAddedWithinTemplStatementsExpected = `<p>This is some text. So is this.</p>`\n\nfunc InlineElementsAreNotPadded() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var2 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var2 == nil {\n\t\t\ttempl_7745c5c3_Var2 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<p>Inline text <b>is spaced properly</b> without adding extra spaces.</p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst InlineElementsAreNotPaddedExpected = `<p>Inline text <b>is spaced properly</b> without adding extra spaces.</p>`\n\nfunc WhiteSpaceInHTMLIsNormalised() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<p>newlines and other whitespace are stripped but it is normalised like HTML.</p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhiteSpaceInHTMLIsNormalisedExpected = `<p>newlines and other whitespace are stripped but it is normalised like HTML.</p>`\n\nfunc WhiteSpaceAroundValues() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<p>templ allows \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(\"strings\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-text-whitespace/template.templ`, Line: 31, Col: 28}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \" to be included in sentences.</p>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhiteSpaceAroundValuesExpected = `<p>templ allows strings to be included in sentences.</p>`\n\nconst WhiteSpaceAroundTemplatedValuesExpected = `<div>templ allows whitespace around templated values.</div>`\n\nfunc WhiteSpaceAroundTemplatedValues(prefix, statement string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var6 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var6 == nil {\n\t\t\ttempl_7745c5c3_Var6 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var7 string\n\t\ttempl_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(prefix)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-text-whitespace/template.templ`, Line: 39, Col: 14}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \" \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var8 string\n\t\ttempl_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(statement)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-text-whitespace/template.templ`, Line: 39, Col: 28}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"</div>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-void/expected.html",
    "content": "<br /><img src=\"https://example.com/image.png\" /><br /><br />\n"
  },
  {
    "path": "generator/test-void/render_test.go",
    "content": "package testvoid\n\nimport (\n\t_ \"embed\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/generator/htmldiff\"\n)\n\n//go:embed expected.html\nvar expected string\n\nfunc Test(t *testing.T) {\n\tcomponent := render()\n\n\tactual, diff, err := htmldiff.Diff(component, expected)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff != \"\" {\n\t\tif err := os.WriteFile(\"actual.html\", []byte(actual), 0644); err != nil {\n\t\t\tt.Errorf(\"failed to write actual.html: %v\", err)\n\t\t}\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "generator/test-void/template.templ",
    "content": "package testvoid\n\ntempl render() {\n\t<br/>\n\t<img src=\"https://example.com/image.png\"/>\n\t<br/>\n\t<br/>\n}\n"
  },
  {
    "path": "generator/test-void/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testvoid\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc render() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<br><img src=\\\"https://example.com/image.png\\\"><br><br>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "generator/test-whitespace-around-go-keywords/render_test.go",
    "content": "package testwhitespacearoundgokeywords\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestTextWhitespace(t *testing.T) {\n\tfor _, test := range []struct {\n\t\tname     string\n\t\tinput    templ.Component\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a true evaluated if statement\",\n\t\t\tinput:    WhitespaceIsConsistentInIf(true, false),\n\t\t\texpected: WhitespaceIsConsistentInTrueIfExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a true evaluated else if statement\",\n\t\t\tinput:    WhitespaceIsConsistentInIf(false, true),\n\t\t\texpected: WhitespaceIsConsistentInTrueElseIfExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a true evaluated else statement\",\n\t\t\tinput:    WhitespaceIsConsistentInIf(false, false),\n\t\t\texpected: WhitespaceIsConsistentInTrueElseExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a false evaluated if statement\",\n\t\t\tinput:    WhitespaceIsConsistentInFalseIf(),\n\t\t\texpected: WhitespaceIsConsistentInFalseIfExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a switch statement with a true case\",\n\t\t\tinput:    WhitespaceIsConsistentInSwitch(1),\n\t\t\texpected: WhitespaceIsConsistentInOneSwitchExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a switch statement with a default case\",\n\t\t\tinput:    WhitespaceIsConsistentInSwitch(2),\n\t\t\texpected: WhitespaceIsConsistentInDefaultSwitchExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a switch statement with no default case and no true cases\",\n\t\t\tinput:    WhitespaceIsConsistentInSwitchNoDefault(),\n\t\t\texpected: WhitespaceIsConsistentInSwitchNoDefaultExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a for statement that runs 0 times\",\n\t\t\tinput:    WhitespaceIsConsistentInFor(0),\n\t\t\texpected: WhitespaceIsConsistentInForZeroExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a for statement that runs 1 times\",\n\t\t\tinput:    WhitespaceIsConsistentInFor(1),\n\t\t\texpected: WhitespaceIsConsistentInForOneExpected,\n\t\t},\n\t\t{\n\t\t\tname:     \"whitespace is consistent in a for statement that runs 3 times\",\n\t\t\tinput:    WhitespaceIsConsistentInFor(3),\n\t\t\texpected: WhitespaceIsConsistentInForThreeExpected,\n\t\t},\n\t} {\n\t\tw := new(strings.Builder)\n\t\terr := test.input.Render(context.Background(), w)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"failed to render: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(test.expected, w.String()); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "generator/test-whitespace-around-go-keywords/template.templ",
    "content": "package testwhitespacearoundgokeywords \n\nimport \"fmt\"\n\ntempl WhitespaceIsConsistentInIf(firstIf, secondIf bool) {\n\t<button>Start</button>\n\tif firstIf {\n\t\t<button>If</button>\n\t} else if secondIf {\n\t\t<button>ElseIf</button>\n\t} else {\n\t\t<button>Else</button>\n\t}\n\t<button>End</button>\n}\n\nconst WhitespaceIsConsistentInTrueIfExpected = `<button>Start</button> <button>If</button> <button>End</button>`\nconst WhitespaceIsConsistentInTrueElseIfExpected = `<button>Start</button> <button>ElseIf</button> <button>End</button>`\nconst WhitespaceIsConsistentInTrueElseExpected = `<button>Start</button> <button>Else</button> <button>End</button>`\n\ntempl WhitespaceIsConsistentInFalseIf() {\n\t<button>Start</button>\n\tif false {\n\t\t<button>Will Not Render</button>\n\t}\n\t<button>End</button>\n}\n\nconst WhitespaceIsConsistentInFalseIfExpected = `<button>Start</button> <button>End</button>`\n\ntempl WhitespaceIsConsistentInSwitch(i int) {\n\t<button>Start</button>\n\tswitch i {\n\t\tcase 1:\n\t\t\t<button>1</button>\n\t\tdefault:\n\t\t\t<button>default</button>\n\t}\n\t<button>End</button>\n}\n\nconst WhitespaceIsConsistentInOneSwitchExpected = `<button>Start</button> <button>1</button> <button>End</button>`\nconst WhitespaceIsConsistentInDefaultSwitchExpected = `<button>Start</button> <button>default</button> <button>End</button>`\n\ntempl WhitespaceIsConsistentInSwitchNoDefault() {\n\t<button>Start</button>\n\tswitch false {\n\t\tcase true:\n\t\t\t<button>Will Not Render</button>\n\t}\n\t<button>End</button>\n}\n\nconst WhitespaceIsConsistentInSwitchNoDefaultExpected = `<button>Start</button> <button>End</button>`\n\ntempl WhitespaceIsConsistentInFor(i int) {\n\t<button>Start</button>\n\tfor j := 0; j < i; j++ {\n\t\t<button>{ fmt.Sprint(j) }</button>\n\t}\n\t<button>End</button>\n}\n\nconst WhitespaceIsConsistentInForZeroExpected = `<button>Start</button> <button>End</button>`\nconst WhitespaceIsConsistentInForOneExpected = `<button>Start</button> <button>0</button> <button>End</button>`\nconst WhitespaceIsConsistentInForThreeExpected = `<button>Start</button> <button>0</button> <button>1</button> <button>2</button> <button>End</button>`\n"
  },
  {
    "path": "generator/test-whitespace-around-go-keywords/template_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage testwhitespacearoundgokeywords\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"fmt\"\n\nfunc WhitespaceIsConsistentInIf(firstIf, secondIf bool) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<button>Start</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif firstIf {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"<button>If</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else if secondIf {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<button>ElseIf</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t} else {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"<button>Else</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<button>End</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhitespaceIsConsistentInTrueIfExpected = `<button>Start</button> <button>If</button> <button>End</button>`\nconst WhitespaceIsConsistentInTrueElseIfExpected = `<button>Start</button> <button>ElseIf</button> <button>End</button>`\nconst WhitespaceIsConsistentInTrueElseExpected = `<button>Start</button> <button>Else</button> <button>End</button>`\n\nfunc WhitespaceIsConsistentInFalseIf() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var2 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var2 == nil {\n\t\t\ttempl_7745c5c3_Var2 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"<button>Start</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tif false {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"<button>Will Not Render</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, \"<button>End</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhitespaceIsConsistentInFalseIfExpected = `<button>Start</button> <button>End</button>`\n\nfunc WhitespaceIsConsistentInSwitch(i int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, \"<button>Start</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tswitch i {\n\t\tcase 1:\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, \"<button>1</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\tdefault:\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, \"<button>default</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, \"<button>End</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhitespaceIsConsistentInOneSwitchExpected = `<button>Start</button> <button>1</button> <button>End</button>`\nconst WhitespaceIsConsistentInDefaultSwitchExpected = `<button>Start</button> <button>default</button> <button>End</button>`\n\nfunc WhitespaceIsConsistentInSwitchNoDefault() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, \"<button>Start</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tswitch false {\n\t\tcase true:\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, \"<button>Will Not Render</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, \"<button>End</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhitespaceIsConsistentInSwitchNoDefaultExpected = `<button>Start</button> <button>End</button>`\n\nfunc WhitespaceIsConsistentInFor(i int) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var5 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var5 == nil {\n\t\t\ttempl_7745c5c3_Var5 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, \"<button>Start</button> \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tfor j := 0; j < i; j++ {\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, \"<button>\")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\tvar templ_7745c5c3_Var6 string\n\t\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(j))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `generator/test-whitespace-around-go-keywords/template.templ`, Line: 59, Col: 25}\n\t\t\t}\n\t\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, \"</button> \")\n\t\t\tif templ_7745c5c3_Err != nil {\n\t\t\t\treturn templ_7745c5c3_Err\n\t\t\t}\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, \"<button>End</button>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nconst WhitespaceIsConsistentInForZeroExpected = `<button>Start</button> <button>End</button>`\nconst WhitespaceIsConsistentInForOneExpected = `<button>Start</button> <button>0</button> <button>End</button>`\nconst WhitespaceIsConsistentInForThreeExpected = `<button>Start</button> <button>0</button> <button>1</button> <button>2</button> <button>End</button>`\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/a-h/templ\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/a-h/parse v0.0.0-20250122154542-74294addb73e\n\tgithub.com/andybalholm/brotli v1.1.0\n\tgithub.com/cenkalti/backoff/v4 v4.3.0\n\tgithub.com/cli/browser v1.3.0\n\tgithub.com/fatih/color v1.16.0\n\tgithub.com/fsnotify/fsnotify v1.7.0\n\tgithub.com/google/go-cmp v0.6.0\n\tgithub.com/natefinch/atomic v1.0.1\n\tgithub.com/rs/cors v1.11.0\n\tgithub.com/stretchr/testify v1.10.0\n\tgolang.org/x/mod v0.26.0\n\tgolang.org/x/net v0.51.0\n\tgolang.org/x/sync v0.16.0\n\tgolang.org/x/tools v0.35.0\n)\n\nrequire (\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/mattn/go-colorable v0.1.13 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgolang.org/x/sys v0.41.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n\n// replace github.com/a-h/parse => /Users/adrian/github.com/a-h/parse\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=\ngithub.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=\ngithub.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=\ngithub.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=\ngithub.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=\ngithub.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=\ngithub.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=\ngithub.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=\ngithub.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=\ngithub.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=\ngithub.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=\ngithub.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngolang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=\ngolang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=\ngolang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=\ngolang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=\ngolang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=\ngolang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=\ngolang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=\ngolang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "handler.go",
    "content": "package templ\n\nimport (\n\t\"net/http\"\n)\n\n// ComponentHandler is a http.Handler that renders components.\ntype ComponentHandler struct {\n\tComponent      Component\n\tStatus         int\n\tContentType    string\n\tErrorHandler   func(r *http.Request, err error) http.Handler\n\tStreamResponse bool\n\tFragmentIDs    []any\n}\n\nconst componentHandlerErrorMessage = \"templ: failed to render template\"\n\nfunc (ch *ComponentHandler) handleRenderErr(w http.ResponseWriter, r *http.Request, err error) {\n\tif ch.ErrorHandler != nil {\n\t\tw.Header().Set(\"Content-Type\", ch.ContentType)\n\t\tch.ErrorHandler(r, err).ServeHTTP(w, r)\n\t\treturn\n\t}\n\thttp.Error(w, componentHandlerErrorMessage, http.StatusInternalServerError)\n}\n\nfunc (ch *ComponentHandler) ServeHTTPBufferedFragment(w http.ResponseWriter, r *http.Request) {\n\t// Since the component may error, write to a buffer first.\n\t// This prevents partial responses from being written to the client.\n\tbuf := GetBuffer()\n\tdefer ReleaseBuffer(buf)\n\n\t// Render the component into io.Discard, but use the buffer for fragments.\n\tif err := RenderFragments(r.Context(), buf, ch.Component, ch.FragmentIDs...); err != nil {\n\t\tch.handleRenderErr(w, r, err)\n\t\treturn\n\t}\n\n\t// The component rendered successfully, we can write the Content-Type and Status.\n\tw.Header().Set(\"Content-Type\", ch.ContentType)\n\tif ch.Status != 0 {\n\t\tw.WriteHeader(ch.Status)\n\t}\n\t// Ignore write error like http.Error() does, because there is\n\t// no way to recover at this point.\n\t_, _ = w.Write(buf.Bytes())\n}\n\nfunc (ch *ComponentHandler) ServeHTTPBufferedComplete(w http.ResponseWriter, r *http.Request) {\n\t// Since the component may error, write to a buffer first.\n\t// This prevents partial responses from being written to the client.\n\tbuf := GetBuffer()\n\tdefer ReleaseBuffer(buf)\n\n\t// Render the component into the buffer.\n\tif err := ch.Component.Render(r.Context(), buf); err != nil {\n\t\tch.handleRenderErr(w, r, err)\n\t\treturn\n\t}\n\n\t// The component rendered successfully, we can write the Content-Type and Status.\n\tw.Header().Set(\"Content-Type\", ch.ContentType)\n\tif ch.Status != 0 {\n\t\tw.WriteHeader(ch.Status)\n\t}\n\t// Ignore write error like http.Error() does, because there is\n\t// no way to recover at this point.\n\t_, _ = w.Write(buf.Bytes())\n}\n\nfunc (ch *ComponentHandler) ServeHTTPBuffered(w http.ResponseWriter, r *http.Request) {\n\t// If fragments are specified, render only those.\n\tif len(ch.FragmentIDs) > 0 {\n\t\tch.ServeHTTPBufferedFragment(w, r)\n\t\treturn\n\t}\n\n\t// Otherwise, render the complete component.\n\tch.ServeHTTPBufferedComplete(w, r)\n}\n\nfunc (ch *ComponentHandler) ServeHTTPStreamed(w http.ResponseWriter, r *http.Request) {\n\t// If streaming, we do not buffer the response, so set the headers immediately.\n\tw.Header().Set(\"Content-Type\", ch.ContentType)\n\tif ch.Status != 0 {\n\t\tw.WriteHeader(ch.Status)\n\t}\n\n\t// Pass fragment names to the context if specified.\n\tif len(ch.FragmentIDs) > 0 {\n\n\t\t// Render the component into io.Discard, but use the buffer for fragments.\n\t\tif err := RenderFragments(r.Context(), w, ch.Component, ch.FragmentIDs...); err != nil {\n\t\t\tch.handleRenderErr(w, r, err)\n\t\t\treturn\n\t\t}\n\t\treturn\n\t}\n\n\t// Render the component into the buffer.\n\tif err := ch.Component.Render(r.Context(), w); err != nil {\n\t\tch.handleRenderErr(w, r, err)\n\t\treturn\n\t}\n}\n\n// ServeHTTP implements the http.Handler interface.\nfunc (ch ComponentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif ch.StreamResponse {\n\t\tch.ServeHTTPStreamed(w, r)\n\t\treturn\n\t}\n\tch.ServeHTTPBuffered(w, r)\n}\n\n// Handler creates a http.Handler that renders the template.\nfunc Handler(c Component, options ...func(*ComponentHandler)) *ComponentHandler {\n\tch := &ComponentHandler{\n\t\tComponent:   c,\n\t\tContentType: \"text/html; charset=utf-8\",\n\t}\n\tfor _, o := range options {\n\t\to(ch)\n\t}\n\treturn ch\n}\n\n// WithStatus sets the HTTP status code returned by the ComponentHandler.\nfunc WithStatus(status int) func(*ComponentHandler) {\n\treturn func(ch *ComponentHandler) {\n\t\tch.Status = status\n\t}\n}\n\n// WithContentType sets the Content-Type header returned by the ComponentHandler.\nfunc WithContentType(contentType string) func(*ComponentHandler) {\n\treturn func(ch *ComponentHandler) {\n\t\tch.ContentType = contentType\n\t}\n}\n\n// WithErrorHandler sets the error handler used if rendering fails.\nfunc WithErrorHandler(eh func(r *http.Request, err error) http.Handler) func(*ComponentHandler) {\n\treturn func(ch *ComponentHandler) {\n\t\tch.ErrorHandler = eh\n\t}\n}\n\n// WithStreaming sets the ComponentHandler to stream the response instead of buffering it.\nfunc WithStreaming() func(*ComponentHandler) {\n\treturn func(ch *ComponentHandler) {\n\t\tch.StreamResponse = true\n\t}\n}\n\n// WithFragments sets the ids of the fragments to render.\n// If not set, all content is rendered.\nfunc WithFragments(ids ...any) func(*ComponentHandler) {\n\treturn func(ch *ComponentHandler) {\n\t\tch.FragmentIDs = ids\n\t}\n}\n"
  },
  {
    "path": "handler_test.go",
    "content": "package templ_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestHandler(t *testing.T) {\n\thello := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\tif _, err := io.WriteString(w, \"Hello\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write string: %v\", err)\n\t\t}\n\t\treturn nil\n\t})\n\terrorComponent := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\tif _, err := io.WriteString(w, \"Hello\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write string: %v\", err)\n\t\t}\n\t\treturn errors.New(\"handler error\")\n\t})\n\tfragmentPage := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\tif _, err := io.WriteString(w, \"page_contents\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfragmentContents := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\t_, err := io.WriteString(w, \"fragment_contents\")\n\t\t\treturn err\n\t\t})\n\t\treturn templ.Fragment(\"fragment\").Render(templ.WithChildren(ctx, fragmentContents), w)\n\t})\n\n\ttype nameFragmentKey struct{}\n\tvar fragmentContentsName = nameFragmentKey{}\n\tfragmentPageWithCustomKey := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\tif _, err := io.WriteString(w, \"page_contents\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfragmentContents := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\t_, err := io.WriteString(w, \"fragment_contents\")\n\t\t\treturn err\n\t\t})\n\t\treturn templ.Fragment(fragmentContentsName).Render(templ.WithChildren(ctx, fragmentContents), w)\n\t})\n\n\ttests := []struct {\n\t\tname             string\n\t\tinput            *templ.ComponentHandler\n\t\texpectedStatus   int\n\t\texpectedMIMEType string\n\t\texpectedBody     string\n\t}{\n\t\t{\n\t\t\tname:             \"handlers return OK by default\",\n\t\t\tinput:            templ.Handler(hello),\n\t\t\texpectedStatus:   http.StatusOK,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"Hello\",\n\t\t},\n\t\t{\n\t\t\tname:             \"handlers return OK by default\",\n\t\t\tinput:            templ.Handler(templ.Raw(`♠ ‘ &spades; &#8216;`)),\n\t\t\texpectedStatus:   http.StatusOK,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"♠ ‘ &spades; &#8216;\",\n\t\t},\n\t\t{\n\t\t\tname:             \"handlers can be configured to return an alternative status code\",\n\t\t\tinput:            templ.Handler(hello, templ.WithStatus(http.StatusNotFound)),\n\t\t\texpectedStatus:   http.StatusNotFound,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"Hello\",\n\t\t},\n\t\t{\n\t\t\tname:             \"handlers can be configured to return an alternative status code and content type\",\n\t\t\tinput:            templ.Handler(hello, templ.WithStatus(http.StatusOK), templ.WithContentType(\"text/csv\")),\n\t\t\texpectedStatus:   http.StatusOK,\n\t\t\texpectedMIMEType: \"text/csv\",\n\t\t\texpectedBody:     \"Hello\",\n\t\t},\n\t\t{\n\t\t\tname:             \"handlers that fail return a 500 error\",\n\t\t\tinput:            templ.Handler(errorComponent),\n\t\t\texpectedStatus:   http.StatusInternalServerError,\n\t\t\texpectedMIMEType: \"text/plain; charset=utf-8\",\n\t\t\texpectedBody:     \"templ: failed to render template\\n\",\n\t\t},\n\t\t{\n\t\t\tname: \"error handling can be customised\",\n\t\t\tinput: templ.Handler(errorComponent, templ.WithErrorHandler(func(r *http.Request, err error) http.Handler {\n\t\t\t\t// Because the error is received, it's possible to log the detail of the request.\n\t\t\t\t// log.Printf(\"template render error for %v %v: %v\", r.Method, r.URL.String(), err)\n\t\t\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\t\t\tw.WriteHeader(http.StatusBadRequest)\n\t\t\t\t\tif _, err := io.WriteString(w, \"custom body\"); err != nil {\n\t\t\t\t\t\tt.Fatalf(\"failed to write string: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})),\n\t\t\texpectedStatus:   http.StatusBadRequest,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"custom body\",\n\t\t},\n\t\t{\n\t\t\tname:             \"fragments can be rendered individually\",\n\t\t\tinput:            templ.Handler(fragmentPage, templ.WithFragments(\"fragment\")),\n\t\t\texpectedStatus:   http.StatusOK,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"fragment_contents\",\n\t\t},\n\t\t{\n\t\t\tname:             \"fragments can be rendered with a custom key type\",\n\t\t\tinput:            templ.Handler(fragmentPageWithCustomKey, templ.WithFragments(fragmentContentsName)),\n\t\t\texpectedStatus:   http.StatusOK,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"fragment_contents\",\n\t\t},\n\t\t{\n\t\t\tname:             \"fragments can be rendered within a page\",\n\t\t\tinput:            templ.Handler(fragmentPage),\n\t\t\texpectedStatus:   http.StatusOK,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"page_contents\\nfragment_contents\",\n\t\t},\n\t\t{\n\t\t\tname:             \"fragments can be streamed\",\n\t\t\tinput:            templ.Handler(fragmentPage, templ.WithFragments(\"fragment\"), templ.WithStreaming()),\n\t\t\texpectedStatus:   http.StatusOK,\n\t\t\texpectedMIMEType: \"text/html; charset=utf-8\",\n\t\t\texpectedBody:     \"fragment_contents\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tw := httptest.NewRecorder()\n\t\t\tr := httptest.NewRequest(\"GET\", \"/test\", nil)\n\t\t\ttt.input.ServeHTTP(w, r)\n\t\t\tif got := w.Result().StatusCode; tt.expectedStatus != got {\n\t\t\t\tt.Errorf(\"expected status %d, got %d\", tt.expectedStatus, got)\n\t\t\t}\n\t\t\tif mimeType := w.Result().Header.Get(\"Content-Type\"); tt.expectedMIMEType != mimeType {\n\t\t\t\tt.Errorf(\"expected content-type %s, got %s\", tt.expectedMIMEType, mimeType)\n\t\t\t}\n\t\t\tbody, err := io.ReadAll(w.Result().Body)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to read body: %v\", err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expectedBody, string(body)); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n\n\tt.Run(\"streaming mode allows responses to be flushed\", func(t *testing.T) {\n\t\tw := httptest.NewRecorder()\n\t\tr := httptest.NewRequest(\"GET\", \"/test\", nil)\n\n\t\tcomponent := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\t// Write part 1.\n\t\t\tif _, err := io.WriteString(w, \"Part 1\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// Flush.\n\t\t\tif f, ok := w.(http.Flusher); ok {\n\t\t\t\tf.Flush()\n\t\t\t}\n\t\t\t// Check partial response.\n\t\t\twr := w.(*httptest.ResponseRecorder)\n\t\t\tactualBody := wr.Body.String()\n\t\t\tif diff := cmp.Diff(\"Part 1\", actualBody); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t\t// Write part 2.\n\t\t\tif _, err := io.WriteString(w, \"\\nPart 2\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\n\t\ttempl.Handler(component, templ.WithStatus(http.StatusCreated), templ.WithStreaming()).ServeHTTP(w, r)\n\t\tif got := w.Result().StatusCode; http.StatusCreated != got {\n\t\t\tt.Errorf(\"expected status %d, got %d\", http.StatusCreated, got)\n\t\t}\n\t\texpectedMIMEType := \"text/html; charset=utf-8\"\n\t\tif mimeType := w.Result().Header.Get(\"Content-Type\"); mimeType != expectedMIMEType {\n\t\t\tt.Errorf(\"expected content-type %s, got %s\", expectedMIMEType, mimeType)\n\t\t}\n\t\tbody, err := io.ReadAll(w.Result().Body)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"failed to read body: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(\"Part 1\\nPart 2\", string(body)); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"streaming mode handles errors\", func(t *testing.T) {\n\t\tw := httptest.NewRecorder()\n\t\tr := httptest.NewRequest(\"GET\", \"/test\", nil)\n\n\t\texpectedErr := errors.New(\"streaming error\")\n\n\t\tcomponent := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\t\tif _, err := io.WriteString(w, \"Body\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn expectedErr\n\t\t})\n\n\t\tvar errorHandlerCalled bool\n\t\terrorHandler := func(r *http.Request, err error) http.Handler {\n\t\t\tif expectedErr != err {\n\t\t\t\tt.Errorf(\"expected error %v, got %v\", expectedErr, err)\n\t\t\t}\n\t\t\terrorHandlerCalled = true\n\t\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\t\t// This will be ignored, because the header has already been written.\n\t\t\t\tw.WriteHeader(http.StatusBadRequest)\n\t\t\t\t// This will be written, but will be appended to the written body.\n\t\t\t\tif _, err := io.WriteString(w, \"Error message\"); err != nil {\n\t\t\t\t\tt.Errorf(\"failed to write error message: %v\", err)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\th := templ.Handler(component,\n\t\t\ttempl.WithStatus(http.StatusCreated),\n\t\t\ttempl.WithStreaming(),\n\t\t\ttempl.WithErrorHandler(errorHandler),\n\t\t)\n\t\th.ServeHTTP(w, r)\n\n\t\tif !errorHandlerCalled {\n\t\t\tt.Error(\"expected error handler to be called\")\n\t\t}\n\t\t// Expect the status code to be 201, not 400, because in streaming mode,\n\t\t// we have to write the header before we can call the error handler.\n\t\tif actualResponseCode := w.Result().StatusCode; http.StatusCreated != actualResponseCode {\n\t\t\tt.Errorf(\"expected status %d, got %d\", http.StatusCreated, actualResponseCode)\n\t\t}\n\t\t// Expect the body to be \"BodyError message\", not just \"Error message\" because\n\t\t// in streaming mode, we've already written part of the body to the response, unlike in\n\t\t// standard mode where the body is written to a buffer before the response is written,\n\t\t// ensuring that partial responses are not sent.\n\t\tactualBody, err := io.ReadAll(w.Result().Body)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"failed to read body: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(\"BodyError message\", string(actualBody)); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "internal/format/format_test.go",
    "content": "package format\n\nimport (\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/internal/prettier\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/tools/txtar\"\n)\n\nfunc TestFormatting(t *testing.T) {\n\tif !prettier.IsAvailable(prettier.DefaultCommand()) {\n\t\tt.Skip(\"Prettier is not available, skipping formatting tests\")\n\t}\n\tfiles, _ := filepath.Glob(\"testdata/*.txt\")\n\tif len(files) == 0 {\n\t\tt.Errorf(\"no test files found\")\n\t}\n\tfor _, file := range files {\n\t\tt.Run(filepath.Base(file), func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\ta, err := txtar.ParseFile(file)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif len(a.Files) != 2 {\n\t\t\t\tt.Fatalf(\"expected 2 files, got %d\", len(a.Files))\n\t\t\t}\n\t\t\tactual, _, err := Templ(a.Files[0].Data, \"\", Config{PrettierRequired: true})\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to format input: %v\", err)\n\t\t\t}\n\t\t\texpected := string(a.Files[1].Data)\n\t\t\tif diff := cmp.Diff(expected, string(actual)); diff != \"\" {\n\t\t\t\tt.Errorf(\"Expected:\\n%s\\nActual:\\n%s\\n\", showWhitespace(expected), showWhitespace(string(actual)))\n\n\t\t\t\texpectedLines := strings.Split(expected, \"\\n\")\n\t\t\t\tactualLines := strings.Split(string(actual), \"\\n\")\n\t\t\t\tif len(expectedLines) != len(actualLines) {\n\t\t\t\t\tt.Errorf(\"Expected %d lines, got %d lines\", len(expectedLines), len(actualLines))\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc showWhitespace(s string) string {\n\ts = strings.ReplaceAll(s, \"\\n\", \"⏎\\n\")\n\ts = strings.ReplaceAll(s, \"\\t\", \"→\")\n\ts = strings.ReplaceAll(s, \" \", \"·\")\n\treturn s\n}\n"
  },
  {
    "path": "internal/format/scriptelement.go",
    "content": "package format\n\nimport (\n\t\"strings\"\n\n\t\"github.com/a-h/templ/internal/prettier\"\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\nconst templScriptPlaceholder = \"templ_go_expression_7331\"\n\n// ScriptElement formats a ScriptElement node, replacing Go expressions with placeholders for formatting.\n// After formatting, it updates the GoCode expressions and their ranges.\nfunc ScriptElement(se *parser.ScriptElement, depth int, prettierCommand string) (err error) {\n\t// Skip empty script elements, as they don't need formatting.\n\tif len(se.Contents) == 0 {\n\t\treturn nil\n\t}\n\n\t// ScriptElements may contain Go expressions in {{ }} blocks. Prettier has no idea how to handle\n\t// that, so we replace them with a placeholder, format the script, and then replace the placeholders\n\t// with the original Go expressions.\n\tvar placeholderContent []parser.ScriptContents\n\tvar scriptWithPlaceholders strings.Builder\n\tfor _, part := range se.Contents {\n\t\tif part.Value != nil {\n\t\t\tscriptWithPlaceholders.WriteString(*part.Value)\n\t\t\tcontinue\n\t\t}\n\t\tif part.GoCode != nil {\n\t\t\tscriptWithPlaceholders.WriteString(templScriptPlaceholder)\n\t\t\tplaceholderContent = append(placeholderContent, part)\n\t\t\tcontinue\n\t\t}\n\t}\n\n\t// <script> elements can have a type attribute that specifies the script type. This is important\n\t// to avoid formatting errors, e.g. attempting to format <script type=\"text/hyperscript\"> with a\n\t// JavaScript formatter.\n\tvar scriptType string\nloop:\n\tfor _, attr := range se.Attributes {\n\t\tswitch attr := attr.(type) {\n\t\tcase *parser.ConstantAttribute:\n\t\t\tif attr.Key.String() == \"type\" {\n\t\t\t\tscriptType = attr.Value\n\t\t\t}\n\t\t\tbreak loop\n\t\t}\n\t}\n\n\t// Use the prettifyElement function to format the script contents.\n\tafter, err := prettier.Element(\"script\", scriptType, scriptWithPlaceholders.String(), depth, prettierCommand)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// If there were no placeholders, set the contents to the formatted script.\n\tif len(placeholderContent) == 0 {\n\t\tse.Contents = []parser.ScriptContents{\n\t\t\t{\n\t\t\t\tValue:               &after,\n\t\t\t\tGoCode:              nil,\n\t\t\t\tInsideStringLiteral: false,\n\t\t\t},\n\t\t}\n\t\treturn nil\n\t}\n\n\tsplit := strings.Split(after, templScriptPlaceholder)\n\tvar appliedPlaceholderCount int\n\tvar newContents []parser.ScriptContents\n\tfor _, part := range split {\n\t\tif part == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tnewContents = append(newContents, parser.ScriptContents{\n\t\t\tValue:               &part,\n\t\t\tGoCode:              nil,\n\t\t\tInsideStringLiteral: false,\n\t\t})\n\t\t// If we had a GoCode part, we need to add it back in.\n\t\tif appliedPlaceholderCount < len(placeholderContent) {\n\t\t\tplaceholder := placeholderContent[appliedPlaceholderCount]\n\t\t\t// Trim horizontal space from the GoCode trailing space, as prettier will add its own.\n\t\t\tif placeholder.GoCode != nil && strings.Contains(string(placeholder.GoCode.TrailingSpace), \" \") {\n\t\t\t\tplaceholder.GoCode.TrailingSpace = parser.SpaceNone\n\t\t\t}\n\t\t\tnewContents = append(newContents, placeholder)\n\t\t\tappliedPlaceholderCount++\n\t\t}\n\t}\n\tse.Contents = newContents\n\n\treturn nil\n}\n"
  },
  {
    "path": "internal/format/styleelement.go",
    "content": "package format\n\nimport (\n\t\"github.com/a-h/templ/internal/prettier\"\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\nfunc StyleElement(se *parser.RawElement, depth int, prettierCommand string) (err error) {\n\tif se.Name != \"style\" {\n\t\treturn nil\n\t}\n\n\t// Skip empty style elements, as they don't need formatting.\n\tif len(se.Contents) == 0 {\n\t\treturn nil\n\t}\n\n\t// Prettyify the style contents.\n\tse.Contents, err = prettier.Element(\"style\", \"text/css\", se.Contents, depth, prettierCommand)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "internal/format/templ.go",
    "content": "package format\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\n\t\"github.com/a-h/templ/internal/imports\"\n\t\"github.com/a-h/templ/internal/prettier\"\n\tparser \"github.com/a-h/templ/parser/v2\"\n\t\"github.com/a-h/templ/parser/v2/visitor\"\n)\n\ntype Config struct {\n\t// PrettierCommand is the command to run to format the content of script and style elements.\n\t// If empty, the default is \"prettier --use-tabs --stdin-filepath $TEMPL_PRETTIER_FILENAME\".\n\tPrettierCommand string\n\t// PrettierRequired indicates that formatting using Prettier must be applied.\n\tPrettierRequired bool\n}\n\n// Templ formats templ source, returning the formatted output, whether it changed, and an error if any.\n// The fileName is used for Go import processing, use an empty name if the source is not from a file.\nfunc Templ(src []byte, fileName string, config Config) (output []byte, changed bool, err error) {\n\tt, err := parser.ParseString(string(src))\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tt.Filepath = fileName\n\tt, err = imports.Process(t)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\n\tif err = applyPrettier(t, config); err != nil {\n\t\treturn nil, false, err\n\t}\n\n\tw := new(bytes.Buffer)\n\tif err = t.Write(w); err != nil {\n\t\treturn nil, false, fmt.Errorf(\"formatting error: %w\", err)\n\t}\n\tout := w.Bytes()\n\tchanged = !bytes.Equal(src, out)\n\treturn out, changed, nil\n}\n\nfunc applyPrettier(t *parser.TemplateFile, config Config) (err error) {\n\t// Check to see if prettier can be run.\n\tif config.PrettierCommand == \"\" {\n\t\tconfig.PrettierCommand = prettier.DefaultCommand()\n\t}\n\tif !prettier.IsAvailable(config.PrettierCommand) {\n\t\tif config.PrettierRequired {\n\t\t\treturn fmt.Errorf(\"prettier command %q is not available, please install it or set a different command using the -prettier-command flag\", config.PrettierCommand)\n\t\t}\n\t\t// Prettier is not available, skip applying it.\n\t\treturn nil\n\t}\n\n\tnodeFormatter := visitor.New()\n\t// Calculate the depth of each ScriptElement and RawElement in the tree so that the formatting is properly indented.\n\tnodeToDepth := make(map[parser.Node]int)\n\tnodeFormatter.HTMLTemplate = func(n *parser.HTMLTemplate) error {\n\t\t// Visit the children first to calculate their depth.\n\t\tfor _, child := range n.Children {\n\t\t\tcalculateNodeDepth(child, nodeToDepth, 1)\n\t\t}\n\t\t// Now that we have the depth of each node, we can format them.\n\t\tfor _, child := range n.Children {\n\t\t\tif err := child.Visit(nodeFormatter); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tnodeFormatter.ScriptElement = func(se *parser.ScriptElement) error {\n\t\tdepth := nodeToDepth[se]\n\t\treturn ScriptElement(se, depth, config.PrettierCommand)\n\t}\n\tnodeFormatter.RawElement = func(re *parser.RawElement) error {\n\t\tdepth := nodeToDepth[re]\n\t\tif re.Name != \"style\" {\n\t\t\treturn nil\n\t\t}\n\t\treturn StyleElement(re, depth, config.PrettierCommand)\n\t}\n\n\treturn nodeFormatter.VisitTemplateFile(t)\n}\n\nfunc calculateNodeDepth(e parser.Node, nodeToDepth map[parser.Node]int, depth int) {\n\tswitch e := e.(type) {\n\tcase *parser.ScriptElement:\n\t\tnodeToDepth[e] = depth\n\tcase *parser.RawElement:\n\t\tnodeToDepth[e] = depth\n\tcase parser.CompositeNode:\n\t\tfor _, child := range e.ChildNodes() {\n\t\t\tcalculateNodeDepth(child, nodeToDepth, depth+1)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/format/testdata/all_children_indented__with_nested_indentation__when_close_tag_is_on_new_line.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<div><p>{ \"the\" }<a href=\"http://example.com\">{ \"data\" }\n</a></p></div>\n}\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n\t\t<p>\n\t\t\t{ \"the\" }\n\t\t\t<a href=\"http://example.com\">\n\t\t\t\t{ \"data\" }\n\t\t\t</a>\n\t\t</p>\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/all_children_indented__with_nested_indentation__when_close_tag_is_on_same_line.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<div><p>{ \"the\" }<a href=\"http://example.com\">{ \"data\" } </a></p></div>\n}\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<div><p>{ \"the\" }<a href=\"http://example.com\">{ \"data\" } </a></p></div>\n}\n"
  },
  {
    "path": "internal/format/testdata/br_and_hr_all_on_one_line_are_not_placed_on_new_lines.txt",
    "content": "-- in --\npackage main\n\ntempl test() {\n\t<div>Linebreaks<br/>used<br/>for<br/>spacing</div>\n}\n-- out --\npackage main\n\ntempl test() {\n\t<div>Linebreaks<br/>used<br/>for<br/>spacing</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/br_elements_are_placed_on_new_lines.txt",
    "content": "-- in --\npackage main\n\ntempl test() {\n\t<div>\n\t\tLinebreaks<br/>and<hr/>rules<br/>for<br/>spacing\n\t</div>\n}\n-- out --\npackage main\n\ntempl test() {\n\t<div>\n\t\tLinebreaks\n\t\t<br/>\n\t\tand\n\t\t<hr/>\n\t\trules\n\t\t<br/>\n\t\tfor\n\t\t<br/>\n\t\tspacing\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/children_indented__closing_elm.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<div><p>{ \"the\" }<a href=\"http://example.com\">{ \"data\" }</a></p>\n    </div>\n}\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n\t\t<p>{ \"the\" }<a href=\"http://example.com\">{ \"data\" }</a></p>\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/children_indented__first_child.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n        <p>{ \"the\" }<a href=\"http://example.com\">{ \"data\" }</a></p></div>\n}\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n\t\t<p>{ \"the\" }<a href=\"http://example.com\">{ \"data\" }</a></p>\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/comments_are_preserved.txt",
    "content": "-- in --\npackage main\n\ntempl test() {\n\t<!-- This is a comment -->\n\t// This is not included in the output.\n\t<div>Some standard templ</div>\n\t/* This is not included in the output too. */\n\t/*\n\t\tLeave this alone.\n\t*/\n}\n-- out --\npackage main\n\ntempl test() {\n\t<!-- This is a comment -->\n\t// This is not included in the output.\n\t<div>Some standard templ</div>\n\t/* This is not included in the output too. */\n\t/*\n\t\tLeave this alone.\n\t*/\n}\n"
  },
  {
    "path": "internal/format/testdata/conditional_expressions_have_the_same_child_indentation_rules_as_regular_elements.txt",
    "content": "-- in --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div id=\"conditional\"\nif addClass {\nclass=\"itWasTrue\"\n}\n>\nContent</div>\n}\n-- out --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div\n\t\tid=\"conditional\"\n\t\tif addClass {\n\t\t\tclass=\"itWasTrue\"\n\t\t}\n\t>\n\t\tContent\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/conditional_expressions_result_in_all_attrs_indented.txt",
    "content": "-- in --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div id=\"conditional\" if addClass {\n\t\tclass=\"itWasTrue\"\n\t}\n\twidth=\"300\">Content</div>\n}\n-- out --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div\n\t\tid=\"conditional\"\n\t\tif addClass {\n\t\t\tclass=\"itWasTrue\"\n\t\t}\n\t\twidth=\"300\"\n\t>Content</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/conditional_expressions_result_in_all_attrs_indented__2.txt",
    "content": "-- in --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div id=\"conditional\"\nif addClass {\nclass=\"itWasTrue\"\n}\nwidth=\"300\">Content</div>\n}\n-- out --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div\n\t\tid=\"conditional\"\n\t\tif addClass {\n\t\t\tclass=\"itWasTrue\"\n\t\t}\n\t\twidth=\"300\"\n\t>Content</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/conditional_expressions_with_else_blocks_are_also_formatted.txt",
    "content": "-- in --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div id=\"conditional\"\nif addClass {\nclass=\"itWasTrue\"\n} else {\n\tclass=\"itWasNotTrue\"\n}\nwidth=\"300\">Content</div>\n}\n-- out --\npackage test\n\ntempl conditionalAttributes(addClass bool) {\n\t<div\n\t\tid=\"conditional\"\n\t\tif addClass {\n\t\t\tclass=\"itWasTrue\"\n\t\t} else {\n\t\t\tclass=\"itWasNotTrue\"\n\t\t}\n\t\twidth=\"300\"\n\t>Content</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/constant_attributes_prerfer_double_quotes__but_use_single_quotes_if_required.txt",
    "content": "-- in --\npackage test\n\ntempl nested() {\n\t<div class=\"double\">double</div>\n\t<div class='single-not-required'>single-not-required</div>\n\t<div data-value='{\"data\":\"value\"}'>single-required</div>\n}\n\n-- out --\npackage test\n\ntempl nested() {\n\t<div class=\"double\">double</div>\n\t<div class=\"single-not-required\">single-not-required</div>\n\t<div data-value='{\"data\":\"value\"}'>single-required</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/css_is_indented_by_one_level.txt",
    "content": "-- in --\npackage test\n\ncss ClassName() {\nbackground-color: #ffffff;\ncolor: { constants.White };\n}\n-- out --\npackage test\n\ncss ClassName() {\n\tbackground-color: #ffffff;\n\tcolor: { constants.White };\n}\n"
  },
  {
    "path": "internal/format/testdata/css_whitespace_is_tidied.txt",
    "content": "-- in --\npackage test\n\ncss ClassName() {\nbackground-color    :   #ffffff\t;\n  color\t:  { constants.White };\n  }\n\t\t\n-- out --\npackage test\n\ncss ClassName() {\n\tbackground-color: #ffffff;\n\tcolor: { constants.White };\n}\n"
  },
  {
    "path": "internal/format/testdata/cssarguments_multiline.txt",
    "content": "-- in --\npackage p\n\ncss Style(\na string,\nb string,\nc string,\n) {\n\tcolor: {a};\n\tbackground-color: {b};\n\tborder-color: {c};\n}\n-- out --\npackage p\n\ncss Style(\n\ta string,\n\tb string,\n\tc string,\n) {\n\tcolor: { a };\n\tbackground-color: { b };\n\tborder-color: { c };\n}\n"
  },
  {
    "path": "internal/format/testdata/empty_elements_stay_on_the_same_line.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n\t\t<p>\n\t\t</p>\n\t</div>\n}\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n\t\t<p></p>\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/for_loops_are_placed_on_a_new_line.txt",
    "content": "-- in --\npackage test\n\ntempl input(items []string) {\n<div>{ \"the\" }<div>{ \"other\" }</div>for _, item := range items {\n<div>{ item }</div>\n}</div>\n}\n-- out --\npackage test\n\ntempl input(items []string) {\n\t<div>\n\t\t{ \"the\" }\n\t\t<div>{ \"other\" }</div>\n\t\tfor _, item := range items {\n\t\t\t<div>{ item }</div>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/formatting_does_not_alter_whitespace.txt",
    "content": "-- in --\npackage test\n\ntempl nested() {\n\t<div>{ \"the\" }<div>{ \"other\" }</div></div>\n}\n\n-- out --\npackage test\n\ntempl nested() {\n\t<div>{ \"the\" }<div>{ \"other\" }</div></div>\n}\n"
  },
  {
    "path": "internal/format/testdata/go_expressions_are_formatted_by_the_go_formatter.txt",
    "content": "-- in --\npackage main\n\n      type Link struct {\nName string\n\t        Url  string\n}\n\nvar a = false;\n\nfunc test() {\n\t      log.Print(\"hoi\")\n\n\t      if (a) {\n      log.Fatal(\"OH NO !\")\n\t}\n}\n\ntempl x() {\n\t<div>Hello World</div>\n}\n-- out --\npackage main\n\ntype Link struct {\n\tName string\n\tUrl  string\n}\n\nvar a = false\n\nfunc test() {\n\tlog.Print(\"hoi\")\n\n\tif a {\n\t\tlog.Fatal(\"OH NO !\")\n\t}\n}\n\ntempl x() {\n\t<div>Hello World</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/go_expressions_have_whitespace_normalised.txt",
    "content": "-- in --\npackage main\n\ntempl x() {\n\t<div>{{\n    hello := \"world\"\n}}</div>\n\t<div id=\"with-spaces\">{{\n\n\t\thello = \"world\"\n\t\t}}</div>\n\t<div id=\"multiline-expressions-stay-multiline\">\n\t\t{{\n\t\thello = \"world\"\n\t\tname := \"foo\"\n\t\t}}\n\t</div>\n}\n-- out --\npackage main\n\ntempl x() {\n\t<div>\n\t\t{{ hello := \"world\" }}\n\t</div>\n\t<div id=\"with-spaces\">\n\t\t{{ hello = \"world\" }}\n\t</div>\n\t<div id=\"multiline-expressions-stay-multiline\">\n\t\t{{\n\t\t\thello = \"world\"\n\t\t\tname := \"foo\"\n\t\t}}\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/godoc_comments_are_preserved.txt",
    "content": "-- in --\npackage main\n\n// test the comment handling.\ntempl test() {\n\tTest\n}\n-- out --\npackage main\n\n// test the comment handling.\ntempl test() {\n\tTest\n}\n"
  },
  {
    "path": "internal/format/testdata/if_statements_are_placed_on_a_new_line.txt",
    "content": "-- in --\npackage test\n\ntempl input(items []string) {\n<div>{ \"the\" }<div>{ \"other\" }</div>if items != nil {\n<div>{ items[0] }</div>\n\t\t} else {\n\t\t\t<div>{ items[1] }</div>\n\t\t}\n</div>\n}\n-- out --\npackage test\n\ntempl input(items []string) {\n\t<div>\n\t\t{ \"the\" }\n\t\t<div>{ \"other\" }</div>\n\t\tif items != nil {\n\t\t\t<div>{ items[0] }</div>\n\t\t} else {\n\t\t\t<div>{ items[1] }</div>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/inline_elements_are_not_placed_on_a_new_line.txt",
    "content": "-- in --\npackage main\n\ntempl test() {\n\t<p>\n\t\tIn a flowing <strong>paragraph</strong>, you can use inline elements.\n\t\tThese <strong>inline elements</strong> can be <strong>styled</strong>\n\t\tand are not placed on new lines.\n\t</p>\n}\n-- out --\npackage main\n\ntempl test() {\n\t<p>\n\t\tIn a flowing <strong>paragraph</strong>, you can use inline elements.\n\t\tThese <strong>inline elements</strong> can be <strong>styled</strong>\n\t\tand are not placed on new lines.\n\t</p>\n}\n"
  },
  {
    "path": "internal/format/testdata/inline_func_blank_lines_no_whitespace.txt",
    "content": "-- in --\npackage main\n\ntype Params struct {\n\tFoo string\n}\n\ntempl Child(p Params) {\n\t<p>{ p.Foo }</p>\n}\n\ntempl Parent(p Params) {\n\t{{\n\t\tbar := (func() string {\n\t\t\tif p.Foo == \"\" {\n\t\t\t\treturn \"Bar\"\n\t\t\t}\n\n\t\t\treturn p.Foo\n\t\t})()\n\t\tbaz := Params{\n\t\t\tFoo: (func() string {\n\t\t\t\tif p.Foo == \"\" {\n\t\t\t\t\treturn \"Baz\"\n\t\t\t\t}\n\n\t\t\t\treturn p.Foo\n\t\t\t})(),\n\t\t}\n\t}}\n\t<div>\n\t\t@Child(Params{\n\t\t\tFoo: (func() string {\n\t\t\t\tif p.Foo == \"\" {\n\t\t\t\t\treturn \"Foo\"\n\t\t\t\t}\n\n\t\t\t\treturn p.Foo\n\t\t\t})(),\n\t\t})\n\t\t<p>{ bar }</p>\n\t\t<p>{ baz.Foo }</p>\n\t</div>\n}\n-- out --\npackage main\n\ntype Params struct {\n\tFoo string\n}\n\ntempl Child(p Params) {\n\t<p>{ p.Foo }</p>\n}\n\ntempl Parent(p Params) {\n\t{{\n\t\tbar := (func() string {\n\t\t\tif p.Foo == \"\" {\n\t\t\t\treturn \"Bar\"\n\t\t\t}\n\n\t\t\treturn p.Foo\n\t\t})()\n\t\tbaz := Params{\n\t\t\tFoo: (func() string {\n\t\t\t\tif p.Foo == \"\" {\n\t\t\t\t\treturn \"Baz\"\n\t\t\t\t}\n\n\t\t\t\treturn p.Foo\n\t\t\t})(),\n\t\t}\n\t}}\n\t<div>\n\t\t@Child(Params{\n\t\t\tFoo: (func() string {\n\t\t\t\tif p.Foo == \"\" {\n\t\t\t\t\treturn \"Foo\"\n\t\t\t\t}\n\n\t\t\t\treturn p.Foo\n\t\t\t})(),\n\t\t})\n\t\t<p>{ bar }</p>\n\t\t<p>{ baz.Foo }</p>\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/multiline_string_literal_indentation_preserved.txt",
    "content": "-- in --\npackage main\n\ntempl x() {\n\t@something(`Hi\nsome cool text\n\nfoo \n\nbar\n\n\t\t`)\n\t@something(`\n\t\tsomething\n\t\t\t\t`,\n\t`\n\t\t\t\tsomething\n\t\t\t\t`,\n\t\t)\n}\n-- out --\npackage main\n\ntempl x() {\n\t@something(`Hi\nsome cool text\n\nfoo \n\nbar\n\n\t\t`)\n\t@something(`\n\t\tsomething\n\t\t\t\t`,\n\t\t`\n\t\t\t\tsomething\n\t\t\t\t`,\n\t)\n}\n"
  },
  {
    "path": "internal/format/testdata/non_empty_elements_with_children_that_are_all_on_the_same_line_are_not_split_into_multiple_lines.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<div><div><b>Text</b></div></div>\n}\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<div><div><b>Text</b></div></div>\n}\n"
  },
  {
    "path": "internal/format/testdata/raw_go_is_formatted.txt",
    "content": "-- in --\npackage test\n\ntempl nameList(items []Item) {\n\t{{ first  := items[0] }}\n}\n-- out --\npackage test\n\ntempl nameList(items []Item) {\n\t{{ first := items[0] }}\n}\n"
  },
  {
    "path": "internal/format/testdata/script_tags_are_not_converted_to_self_closing_elements.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<script src=\"https://example.com/myscript.js\"></script>\n}\n\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<script src=\"https://example.com/myscript.js\"></script>\n}\n"
  },
  {
    "path": "internal/format/testdata/scriptarguments_multiline.txt",
    "content": "-- in --\npackage p\n\nscript Style(\na string,\nb string,\nc string,\n) {\n\tconsole.log(a, b, c);\n}\n-- out --\npackage p\n\nscript Style(\n\ta string,\n\tb string,\n\tc string,\n) {\n\tconsole.log(a, b, c);\n}\n"
  },
  {
    "path": "internal/format/testdata/scriptelement_contents_are_formatted.txt",
    "content": "-- in --\npackage test\n\ntempl script(data string) {\n\t<script>\n  function log(  something)     {\n\t  console.log(something   );\n\t\t}\n\t</script>\n}\n\n-- out --\npackage test\n\ntempl script(data string) {\n\t<script>\n\t\tfunction log(something) {\n\t\t\tconsole.log(something);\n\t\t}\n\t</script>\n}\n"
  },
  {
    "path": "internal/format/testdata/scriptelements_hyperscript_is_ignored.txt",
    "content": "-- in --\npackage test\n\ntempl script(data string) {\n\t<script type=\"text/hyperscript\">\n  on mousedown\n    halt the event -- prevent text selection...\n    -- do other stuff...\n  end\n\t</script>\n\t<script>\n\t  var x = \"abc\";\n\t</script>\n}\n\n-- out --\npackage test\n\ntempl script(data string) {\n\t<script type=\"text/hyperscript\">\n\t\ton mousedown\n\t\t  halt the event -- prevent text selection...\n\t\t  -- do other stuff...\n\t\tend\n\t</script>\n\t<script>\n\t\tvar x = \"abc\";\n\t</script>\n}\n"
  },
  {
    "path": "internal/format/testdata/scriptelements_with_go_code_are_formatted.txt",
    "content": "-- in --\npackage test\n\ntempl script(data string) {\n\t<script>\n  function log(  {{ data }})     {\n\t  console.log({{data}}   );\n\t\t}\n\t</script>\n}\n\n-- out --\npackage test\n\ntempl script(data string) {\n\t<script>\n\t\tfunction log({{ data }}) {\n\t\t\tconsole.log({{ data }});\n\t\t}\n\t</script>\n}\n"
  },
  {
    "path": "internal/format/testdata/scriptelements_with_multiple_go_code_sections_are_formatted.txt",
    "content": "-- in --\npackage test\n\ntempl script(data string) {\n\t<script>\n\t\tvar a = {{ data }}\n\t\tvar b = \"{{ data }}\"\n\t\tvar c = '{{ data }}'\n\t\tvar d = `{{ data }}`\n\t</script>\n}\n\n-- out --\npackage test\n\ntempl script(data string) {\n\t<script>\n\t\tvar a = {{ data }}\n\t\tvar b = \"{{ data }}\"\n\t\tvar c = '{{ data }}'\n\t\tvar d = `{{ data }}`\n\t</script>\n}\n"
  },
  {
    "path": "internal/format/testdata/scriptelements_within_templ_expressions_are_formatted.txt",
    "content": "-- in --\npackage test\n\ntempl script(c templ.Component) {\n\t@c() {\n\t\t<script>\n\t\t\tvar a = {{ data }}\n\t\t\tvar b = \"{{ data }}\"\n\t\t\tvar c = '{{ data }}'\n\t\t\tvar d = `{{ data }}`\n\t\t</script>\n\t}\n}\n\n-- out --\npackage test\n\ntempl script(c templ.Component) {\n\t@c() {\n\t\t<script>\n\t\t\tvar a = {{ data }}\n\t\t\tvar b = \"{{ data }}\"\n\t\t\tvar c = '{{ data }}'\n\t\t\tvar d = `{{ data }}`\n\t\t</script>\n\t}\n}\n"
  },
  {
    "path": "internal/format/testdata/spacing_between_string_expressions_is_kept.txt",
    "content": "-- in --\npackage main\n\ntempl x() {\n    <div>{firstName} {lastName}</div>\n}\n-- out --\npackage main\n\ntempl x() {\n\t<div>{ firstName } { lastName }</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/spacing_between_string_expressions_is_not_magically_added.txt",
    "content": "-- in --\npackage main\n\ntempl x() {\n    <div>{pt1}{pt2}</div>\n}\n-- out --\npackage main\n\ntempl x() {\n\t<div>{ pt1 }{ pt2 }</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/spacing_between_string_spreads_attributes_is_kept.txt",
    "content": "-- in --\npackage main\n\ntempl x() {\n    <div>{firstName...} {lastName...}</div>\n}\n-- out --\npackage main\n\ntempl x() {\n\t<div>{ firstName... } { lastName... }</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/styleelements_are_formatted.txt",
    "content": "-- in --\npackage test\n\ntempl style(data string) {\n\t<style>\n   body   {\n  margin: 0;\n   font-family: system-ui, sans-serif;\n\t\tbackground-color: #f4f4f4;\n  color: #333;\n}\n\t</style>\n}\n\n-- out --\npackage test\n\ntempl style(data string) {\n\t<style>\n\t\tbody {\n\t\t\tmargin: 0;\n\t\t\tfont-family: system-ui, sans-serif;\n\t\t\tbackground-color: #f4f4f4;\n\t\t\tcolor: #333;\n\t\t}\n\t</style>\n}\n"
  },
  {
    "path": "internal/format/testdata/switch_statements_are_placed_on_a_new_line.txt",
    "content": "-- in --\npackage test\n\ntempl input(items []string) {\n<div>{ \"the\" }<div>{ \"other\" }</div>switch items[0] {\n\tcase \"a\":\n<div>{ items[0] }</div>\n\tcase \"b\":\n<div>{ items[1] }</div>\n}</div>\n}\n-- out --\npackage test\n\ntempl input(items []string) {\n\t<div>\n\t\t{ \"the\" }\n\t\t<div>{ \"other\" }</div>\n\t\tswitch items[0] {\n\t\t\tcase \"a\":\n\t\t\t\t<div>{ items[0] }</div>\n\t\t\tcase \"b\":\n\t\t\t\t<div>{ items[1] }</div>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/tables_are_formatted_well.txt",
    "content": "-- in --\npackage test\n\ntempl table(accountNumber string, registration string) {\n\t<table>\n\t       <tr>\n\t\t       <th width=\"20%\">Your account number</th>\n\t\t       <td width=\"80%\">{ accountNumber }</td>\n\t       </tr>\n\t       <tr>\n\t\t       <td>Registration</td>\n\t\t       <td>{ strings.ToUpper(registration) }</td>\n\t       </tr>\n\t</table>\n}\n-- out --\npackage test\n\ntempl table(accountNumber string, registration string) {\n\t<table>\n\t\t<tr>\n\t\t\t<th width=\"20%\">Your account number</th>\n\t\t\t<td width=\"80%\">{ accountNumber }</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td>Registration</td>\n\t\t\t<td>{ strings.ToUpper(registration) }</td>\n\t\t</tr>\n\t</table>\n}\n"
  },
  {
    "path": "internal/format/testdata/templ_expression_attributes_are_formatted_correctly_when_multiline.txt",
    "content": "-- in --\npackage main\n\ntempl x(id string, class string) {\n<button\nid={id}\nname={\n      \"name\"\n  }\nclass={ \n      \"blue\",\n    class,\n\t\tmap[string]bool{\n\t\t\"a\": true,\n\t\t},\n}\n></button>\n}\n-- out --\npackage main\n\ntempl x(id string, class string) {\n\t<button\n\t\tid={ id }\n\t\tname={ \"name\" }\n\t\tclass={\n\t\t\t\"blue\",\n\t\t\tclass,\n\t\t\tmap[string]bool{\n\t\t\t\t\"a\": true,\n\t\t\t},\n\t\t}\n\t></button>\n}\n"
  },
  {
    "path": "internal/format/testdata/templ_expression_elements_are_formatted_the_same_as_other_elements.txt",
    "content": "-- in --\npackage main\n\ntempl x() {\n\t<li>\n\t\t<a href=\"/\">\n\t    Home\n\t    @hello(\"home\") {\n                data\n                }\n     </a>\n\t</li>\n}\n-- out --\npackage main\n\ntempl x() {\n\t<li>\n\t\t<a href=\"/\">\n\t\t\tHome\n\t\t\t@hello(\"home\") {\n\t\t\t\tdata\n\t\t\t}\n\t\t</a>\n\t</li>\n}\n"
  },
  {
    "path": "internal/format/testdata/templatearguments_multiline_with_generics.txt",
    "content": "-- in --\npackage p\n\ntempl List(\nlist1 list[item],\nlist2 list[item],\nlist3 list[item],\n) {\n\t<div></div>\n}\n-- out --\npackage p\n\ntempl List(\n\tlist1 list[item],\n\tlist2 list[item],\n\tlist3 list[item],\n) {\n\t<div></div>\n}\n"
  },
  {
    "path": "internal/format/testdata/templatefile_can_be_round_tripped.txt",
    "content": "-- in --\npackage goof\n\ntempl Hello() {\n\tHello\n}\n\n-- out --\npackage goof\n\ntempl Hello() {\n\tHello\n}\n"
  },
  {
    "path": "internal/format/testdata/templatefile_can_start_with_comments.txt",
    "content": "-- in --\n// Go comment\npackage goof\n\ntempl Hello() {\n\tHello\n}\n-- out --\n// Go comment\npackage goof\n\ntempl Hello() {\n\tHello\n}\n"
  },
  {
    "path": "internal/format/testdata/templatefile_can_start_with_comments_and_whitespace.txt",
    "content": "-- in --\n// Go comment\n\npackage goof\n\ntempl Hello() {\n\tHello\n}\n-- out --\n// Go comment\n\npackage goof\n\ntempl Hello() {\n\tHello\n}\n"
  },
  {
    "path": "internal/format/testdata/templatefile_can_start_with_multiline_comments_and_whitespace.txt",
    "content": "-- in --\n/********************\n* multiline message *\n********************/\n\npackage goof\n\ntempl Hello() {\n\tHello\n}\n-- out --\n/********************\n* multiline message *\n********************/\n\npackage goof\n\ntempl Hello() {\n\tHello\n}\n"
  },
  {
    "path": "internal/format/testdata/templatefile_can_start_with_multiple_comments_and_whitespace.txt",
    "content": "-- in --\n// Go comment\n\n/* Multiline comment on a single line */\n\n/*\n\nMulti-line comment on multiple lines\n\n*/\n\npackage goof\n\ntempl Hello() {\n\tHello\n}\n-- out --\n// Go comment\n\n/* Multiline comment on a single line */\n\n/*\n\nMulti-line comment on multiple lines\n\n*/\n\npackage goof\n\ntempl Hello() {\n\tHello\n}\n"
  },
  {
    "path": "internal/format/testdata/templateheader_with_build_tags.txt",
    "content": "-- in --\n//go:build dev\n\npackage p\n\n-- out --\n//go:build dev\n\npackage p\n\n"
  },
  {
    "path": "internal/format/testdata/templelement_multiline_block_containing_multiline_block.txt",
    "content": "-- in --\npackage p\n\ntempl f() {\n@Other(\n\t\t\tp.Test,\n\"s\",\n){\n\t@another.Component(\n\t\t\tp.Test,\n\t\t\t3,\n\"s\",\n){\n\t<p>hello</p>\n}\n\t}\n}\n-- out --\npackage p\n\ntempl f() {\n\t@Other(\n\t\tp.Test,\n\t\t\"s\",\n\t) {\n\t\t@another.Component(\n\t\t\tp.Test,\n\t\t\t3,\n\t\t\t\"s\",\n\t\t) {\n\t\t\t<p>hello</p>\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/format/testdata/templelement_multiline_block_indentation.txt",
    "content": "-- in --\npackage p\n\ntempl f() {\n\t@Other(\n\t\t\tp.Test,\n\"s\",\n){\n\t<p>hello</p>\n\t}\n}\n-- out --\npackage p\n\ntempl f() {\n\t@Other(\n\t\tp.Test,\n\t\t\"s\",\n\t) {\n\t\t<p>hello</p>\n\t}\n}\n"
  },
  {
    "path": "internal/format/testdata/templelement_multiline_in_div.txt",
    "content": "-- in --\npackage p\n\ntempl f() {\n\t<div>\n\t@Other(\n\t\t\tp.Test,\n\"s\",\n\t\t)\n\t</div>\n}\n-- out --\npackage p\n\ntempl f() {\n\t<div>\n\t\t@Other(\n\t\t\tp.Test,\n\t\t\t\"s\",\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/templelement_param_spacing.txt",
    "content": "-- in --\npackage p\n\ntempl f() {\n\t@Other(p.Test,\"s\")\n}\n-- out --\npackage p\n\ntempl f() {\n\t@Other(p.Test, \"s\")\n}\n"
  },
  {
    "path": "internal/format/testdata/templelement_simple_block_indentation.txt",
    "content": "-- in --\npackage p\n\ntempl f() {\n\t@Other(p.Test, \"s\"){\n\t<p>hello</p>\n\t}\n}\n-- out --\npackage p\n\ntempl f() {\n\t@Other(p.Test, \"s\") {\n\t\t<p>hello</p>\n\t}\n}\n"
  },
  {
    "path": "internal/format/testdata/templelement_simple_in_div.txt",
    "content": "-- in --\npackage p\n\ntempl f() {\n\t<div>\n\t@Other(p.Test, \"s\")\n\t</div>\n}\n-- out --\npackage p\n\ntempl f() {\n\t<div>\n\t\t@Other(p.Test, \"s\")\n\t</div>\n}\n"
  },
  {
    "path": "internal/format/testdata/templelement_simple_no_change.txt",
    "content": "-- in --\npackage p\n\ntempl f() {\n\t@Other(p.Test)\n}\n-- out --\npackage p\n\ntempl f() {\n\t@Other(p.Test)\n}\n"
  },
  {
    "path": "internal/format/testdata/void_elements_are_converted_to_self_closing_elements.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<area>\n\t<area></area>\n\t<base>\n\t<base></base>\n\t<br>\n\t<br></br>\n\t<col>\n\t<col></col>\n\t<command>\n\t<command></command>\n\t<embed>\n\t<embed></embed>\n\t<hr>\n\t<hr></hr>\n\t<img>\n\t<img></img>\n\t<input>\n\t<input></input>\n\t<input>Text\n\t<input>Text</input>\n\t<keygen>\n\t<keygen></keygen>\n\t<link>\n\t<link></link>\n\t<meta>\n\t<meta></meta>\n\t<param>\n\t<param></param>\n\t<source>\n\t<source></source>\n\t<track>\n\t<track></track>\n\t<wbr>\n\t<wbr></wbr>\n}\n\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<area/>\n\t<area/>\n\t<base/>\n\t<base/>\n\t<br/>\n\t<br/>\n\t<col/>\n\t<col/>\n\t<command/>\n\t<command/>\n\t<embed/>\n\t<embed/>\n\t<hr/>\n\t<hr/>\n\t<img/>\n\t<img/>\n\t<input/>\n\t<input/>\n\t<input/>Text\n\t<input/>Text\n\t<keygen/>\n\t<keygen/>\n\t<link/>\n\t<link/>\n\t<meta/>\n\t<meta/>\n\t<param/>\n\t<param/>\n\t<source/>\n\t<source/>\n\t<track/>\n\t<track/>\n\t<wbr/>\n\t<wbr/>\n}\n"
  },
  {
    "path": "internal/format/testdata/when_an_element_contains_children_that_are_on_new_lines__the_children_are_indented.txt",
    "content": "-- in --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n\t<div><b>Text</b></div></div>\n}\n-- out --\npackage test\n\ntempl input(value, validation string) {\n\t<div>\n\t\t<div><b>Text</b></div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/htmlfind/htmlfind.go",
    "content": "package htmlfind\n\nimport (\n\t\"io\"\n\n\t\"golang.org/x/net/html\"\n)\n\n// AllReader returns all nodes that match the given function.\nfunc AllReader(r io.Reader, f Matcher) (nodes []*html.Node, err error) {\n\troot, err := html.Parse(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn All(root, f), nil\n}\n\n// All returns all nodes that match the given function.\nfunc All(n *html.Node, f Matcher) (nodes []*html.Node) {\n\tif f(n) {\n\t\tnodes = append(nodes, n)\n\t}\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tnodes = append(nodes, All(c, f)...)\n\t}\n\treturn nodes\n}\n\n// Matcher is a function that matches HTML nodes.\ntype Matcher func(*html.Node) bool\n\n// Attribute is a key-value pair for an HTML element.\ntype Attribute struct {\n\tName, Value string\n}\n\n// Attr is a constructor for Attribute.\nfunc Attr(name, value string) Attribute {\n\treturn Attribute{name, value}\n}\n\n// Element returns a Matcher that matches an HTML element with the given name and attributes.\nfunc Element(name string, attrs ...Attribute) Matcher {\n\treturn func(n *html.Node) bool {\n\t\tif n.Type != html.ElementNode {\n\t\t\treturn false\n\t\t}\n\t\tif n.Data != name {\n\t\t\treturn false\n\t\t}\n\t\tfor _, a := range attrs {\n\t\t\tif getAttributeValue(n, a.Name) != a.Value {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n}\n\nfunc getAttributeValue(n *html.Node, name string) string {\n\tfor _, a := range n.Attr {\n\t\tif a.Key == name {\n\t\t\treturn a.Val\n\t\t}\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "internal/htmlfind/htmlfind_test.go",
    "content": "package htmlfind_test\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/internal/htmlfind\"\n\t\"golang.org/x/net/html\"\n)\n\nfunc TestFind(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tinput  string\n\t\tfind   htmlfind.Matcher\n\t\tassert func(t *testing.T, nodes []*html.Node)\n\t}{\n\t\t{\n\t\t\tname:  \"find a paragraph\",\n\t\t\tinput: \"<div><p>hello</p></div>\",\n\t\t\tfind:  htmlfind.Element(\"p\"),\n\t\t\tassert: func(t *testing.T, nodes []*html.Node) {\n\t\t\t\tif len(nodes) != 1 {\n\t\t\t\t\tt.Fatalf(\"expected 1 node, got %d\", len(nodes))\n\t\t\t\t}\n\t\t\t\tn := nodes[0]\n\t\t\t\tif n.Data != \"p\" {\n\t\t\t\t\tt.Errorf(\"expected p, got %s\", n.Data)\n\t\t\t\t}\n\t\t\t\tif n.FirstChild.Data != \"hello\" {\n\t\t\t\t\tt.Errorf(\"expected hello, got %s\", n.FirstChild.Data)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"find a div with a specific attribute\",\n\t\t\tinput: `<div class=\"a\">\n\t\t\t  <div class=\"b\">\n\t\t\t\t  <div class=\"c\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>`,\n\t\t\tfind: htmlfind.Element(\"div\", htmlfind.Attr(\"class\", \"b\")),\n\t\t\tassert: func(t *testing.T, nodes []*html.Node) {\n\t\t\t\tif len(nodes) != 1 {\n\t\t\t\t\tt.Fatalf(\"expected 1 node, got %d\", len(nodes))\n\t\t\t\t}\n\t\t\t\tn := nodes[0]\n\t\t\t\tif n.Data != \"div\" {\n\t\t\t\t\tt.Errorf(\"expected div, got %s\", n.Data)\n\t\t\t\t}\n\t\t\t\tif n.Attr[0].Val != \"b\" {\n\t\t\t\t\tt.Errorf(\"expected b, got %s\", n.Attr[0].Val)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"find multiple divs with a specific attribute\",\n\t\t\tinput: `<div class=\"a\">\n\t\t\t  <div class=\"b\">\n\t\t\t\t  Content A\n\t\t\t\t</div>\n\t\t\t\t<div noclass></div>\n\t\t\t\t<div class=\"b\">\n\t\t\t\t  Content B\n\t\t\t\t</div>\n\t\t\t\t<div class=\"c\">\n\t\t\t\t</div>\n\t\t\t</div>`,\n\t\t\tfind: htmlfind.Element(\"div\", htmlfind.Attr(\"class\", \"b\")),\n\t\t\tassert: func(t *testing.T, nodes []*html.Node) {\n\t\t\t\tif len(nodes) != 2 {\n\t\t\t\t\tt.Fatalf(\"expected 2 nodes, got %d\", len(nodes))\n\t\t\t\t}\n\t\t\t\tfor _, n := range nodes {\n\t\t\t\t\tif n.Data != \"div\" {\n\t\t\t\t\t\tt.Errorf(\"expected div, got %s\", n.Data)\n\t\t\t\t\t}\n\t\t\t\t\tif n.Attr[0].Val != \"b\" {\n\t\t\t\t\t\tt.Errorf(\"expected b, got %s\", n.Attr[0].Val)\n\t\t\t\t\t}\n\t\t\t\t\tif strings.TrimSpace(n.FirstChild.Data) != \"Content A\" && strings.TrimSpace(n.FirstChild.Data) != \"Content B\" {\n\t\t\t\t\t\tt.Errorf(\"expected Content A or Content B, got %s\", n.FirstChild.Data)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tr := strings.NewReader(tt.input)\n\t\t\tresults, err := htmlfind.AllReader(r, tt.find)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif tt.assert == nil {\n\t\t\t\tt.Fatalf(\"no assertion provided\")\n\t\t\t}\n\t\t\ttt.assert(t, results)\n\t\t})\n\t}\n\n\tt.Run(\"invalid HTML returns an error\", func(t *testing.T) {\n\t\tvar r errorReader\n\t\tfinder := func(n *html.Node) bool {\n\t\t\treturn n.Data == \"p\"\n\t\t}\n\t\t_, err := htmlfind.AllReader(r, finder)\n\t\tif err != errFailedToRead {\n\t\t\tt.Fatalf(\"expected an error, got %v\", err)\n\t\t}\n\t})\n}\n\nvar errFailedToRead = errors.New(\"failed to read\")\n\ntype errorReader struct{}\n\nfunc (errorReader) Read(p []byte) (n int, err error) {\n\treturn 0, errFailedToRead\n}\n"
  },
  {
    "path": "internal/imports/process.go",
    "content": "package imports\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/format\"\n\t\"go/token\"\n\t\"path\"\n\t\"slices\"\n\t\"strconv\"\n\t\"strings\"\n\n\tgoparser \"go/parser\"\n\n\t\"golang.org/x/sync/errgroup\"\n\t\"golang.org/x/tools/go/ast/astutil\"\n\t\"golang.org/x/tools/imports\"\n\n\t\"github.com/a-h/templ/generator\"\n\t\"github.com/a-h/templ/parser/v2\"\n)\n\nvar internalImports = []string{\"github.com/a-h/templ\", \"github.com/a-h/templ/runtime\"}\n\nfunc convertTemplToGoURI(templURI string) (isTemplFile bool, goURI string) {\n\tbase, fileName := path.Split(templURI)\n\tif !strings.HasSuffix(fileName, \".templ\") {\n\t\treturn\n\t}\n\treturn true, base + (strings.TrimSuffix(fileName, \".templ\") + \"_templ.go\")\n}\n\nvar fset = token.NewFileSet()\n\n// isPackageUsedInAST checks if a package name is referenced in the AST.\n// It walks the AST looking for selector expressions like pkgName.Something.\nfunc isPackageUsedInAST(file *ast.File, pkgName string) (isPackageUsed bool) {\n\tast.Inspect(file, func(n ast.Node) bool {\n\t\t// Look for selector expressions like pkgName.Something\n\t\tif sel, ok := n.(*ast.SelectorExpr); ok {\n\t\t\tif ident, ok := sel.X.(*ast.Ident); ok {\n\t\t\t\tif ident.Name == pkgName {\n\t\t\t\t\tisPackageUsed = true\n\t\t\t\t\t// Stop walking.\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Continue walking.\n\t\treturn true\n\t})\n\treturn isPackageUsed\n}\n\nfunc updateImports(name, src string) (updated []*ast.ImportSpec, parsedFile *ast.File, err error) {\n\t// Apply auto imports.\n\tupdatedGoCode, err := imports.Process(name, []byte(src), nil)\n\tif err != nil {\n\t\treturn updated, nil, fmt.Errorf(\"failed to process go code %q: %w\", src, err)\n\t}\n\t// Get updated imports.\n\tgofile, err := goparser.ParseFile(fset, name, updatedGoCode, goparser.ParseComments)\n\tif err != nil {\n\t\treturn updated, nil, fmt.Errorf(\"failed to get imports from updated go code: %w\", err)\n\t}\n\tfor _, imp := range gofile.Imports {\n\t\tif !slices.Contains(internalImports, strings.Trim(imp.Path.Value, \"\\\"\")) {\n\t\t\tupdated = append(updated, imp)\n\t\t}\n\t}\n\treturn updated, gofile, nil\n}\n\nfunc Process(t *parser.TemplateFile) (*parser.TemplateFile, error) {\n\tif t.Filepath == \"\" {\n\t\treturn t, nil\n\t}\n\tisTemplFile, fileName := convertTemplToGoURI(t.Filepath)\n\tif !isTemplFile {\n\t\treturn t, fmt.Errorf(\"invalid filepath: %s\", t.Filepath)\n\t}\n\n\t// The first node always contains existing imports.\n\t// If there isn't one, create it.\n\tif len(t.Nodes) == 0 {\n\t\tt.Nodes = append(t.Nodes, &parser.TemplateFileGoExpression{})\n\t}\n\t// If there is one, ensure it is a Go expression.\n\tif _, ok := t.Nodes[0].(*parser.TemplateFileGoExpression); !ok {\n\t\tt.Nodes = append([]parser.TemplateFileNode{&parser.TemplateFileGoExpression{}}, t.Nodes...)\n\t}\n\n\t// Find all existing imports.\n\timportsNode := t.Nodes[0].(*parser.TemplateFileGoExpression)\n\n\t// Generate code.\n\tgw := bytes.NewBuffer(nil)\n\tvar updatedImports []*ast.ImportSpec\n\tvar generatedCodeAST *ast.File\n\tvar eg errgroup.Group\n\teg.Go(func() (err error) {\n\t\tif _, err := generator.Generate(t, gw); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to generate go code: %w\", err)\n\t\t}\n\t\tupdatedImports, generatedCodeAST, err = updateImports(fileName, gw.String())\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get imports from generated go code: %w\", err)\n\t\t}\n\t\treturn nil\n\t})\n\n\tvar firstGoNodeInTemplate *ast.File\n\t// Update the template with the imports.\n\t// Ensure that there is a Go expression to add the imports to as the first node.\n\teg.Go(func() (err error) {\n\t\tfirstGoNodeInTemplate, err = goparser.ParseFile(fset, fileName, t.Package.Expression.Value+\"\\n\"+importsNode.Expression.Value, goparser.AllErrors|goparser.ParseComments)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse imports section: %w\", err)\n\t\t}\n\t\treturn nil\n\t})\n\n\t// Wait for completion of both parts.\n\tif err := eg.Wait(); err != nil {\n\t\treturn t, err\n\t}\n\t// Delete unused imports.\n\tfor _, imp := range firstGoNodeInTemplate.Imports {\n\t\tif !containsImport(updatedImports, imp) {\n\t\t\tname, path, err := getImportDetails(imp)\n\t\t\tif err != nil {\n\t\t\t\treturn t, err\n\t\t\t}\n\t\t\t// Check if this is a hyphenated import that might still be used\n\t\t\t// (goimports can't match css-classes to cssclasses).\n\t\t\tif strings.Contains(path, \"-\") {\n\t\t\t\tidentName := getPackageIdentifier(name, path)\n\t\t\t\tif isPackageUsedInAST(generatedCodeAST, identName) {\n\t\t\t\t\t// Import is used, don't delete it.\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tastutil.DeleteNamedImport(fset, firstGoNodeInTemplate, name, path)\n\t\t}\n\t}\n\t// Add imports, if there are any to add.\n\tfor _, imp := range updatedImports {\n\t\tif !containsImport(firstGoNodeInTemplate.Imports, imp) {\n\t\t\tname, path, err := getImportDetails(imp)\n\t\t\tif err != nil {\n\t\t\t\treturn t, err\n\t\t\t}\n\t\t\tastutil.AddNamedImport(fset, firstGoNodeInTemplate, name, path)\n\t\t}\n\t}\n\t// Edge case: reinsert the import to use import syntax without parentheses.\n\tif len(firstGoNodeInTemplate.Imports) == 1 {\n\t\tname, path, err := getImportDetails(firstGoNodeInTemplate.Imports[0])\n\t\tif err != nil {\n\t\t\treturn t, err\n\t\t}\n\t\tastutil.DeleteNamedImport(fset, firstGoNodeInTemplate, name, path)\n\t\tastutil.AddNamedImport(fset, firstGoNodeInTemplate, name, path)\n\t}\n\t// Write out the Go code with the imports.\n\tupdatedGoCode := new(strings.Builder)\n\terr := format.Node(updatedGoCode, fset, firstGoNodeInTemplate)\n\tif err != nil {\n\t\treturn t, fmt.Errorf(\"failed to write updated go code: %w\", err)\n\t}\n\t// Remove the package statement from the node, by cutting the first line of the file.\n\timportsNode.Expression.Value = strings.TrimSpace(strings.SplitN(updatedGoCode.String(), \"\\n\", 2)[1])\n\tif len(updatedImports) == 0 && importsNode.Expression.Value == \"\" {\n\t\tt.Nodes = t.Nodes[1:]\n\t\treturn t, nil\n\t}\n\tt.Nodes[0] = importsNode\n\treturn t, nil\n}\n\nfunc getImportDetails(imp *ast.ImportSpec) (name, importPath string, err error) {\n\tif imp.Name != nil {\n\t\tname = imp.Name.Name\n\t}\n\tif imp.Path != nil {\n\t\timportPath, err = strconv.Unquote(imp.Path.Value)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"failed to unquote package path %s: %w\", imp.Path.Value, err)\n\t\t\treturn\n\t\t}\n\t}\n\treturn name, importPath, nil\n}\n\nfunc getPackageIdentifier(name, importPath string) string {\n\t// If there's an explicit alias, use it.\n\tif name != \"\" {\n\t\treturn name\n\t}\n\t// Extract package name from path.\n\tlastSlash := strings.LastIndex(importPath, \"/\")\n\tpkgName := importPath\n\tif lastSlash >= 0 {\n\t\tpkgName = importPath[lastSlash+1:]\n\t}\n\t// Remove hyphens for the implicit identifier.\n\treturn strings.ReplaceAll(pkgName, \"-\", \"\")\n}\n\nfunc containsImport(imports []*ast.ImportSpec, spec *ast.ImportSpec) bool {\n\tfor _, imp := range imports {\n\t\tif imp.Path.Value == spec.Path.Value {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "internal/imports/process_test.go",
    "content": "package imports\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/cmd/templ/testproject\"\n\t\"github.com/a-h/templ/parser/v2\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/tools/txtar\"\n)\n\nfunc TestFormatting(t *testing.T) {\n\tfiles, _ := filepath.Glob(\"testdata/*.txtar\")\n\tif len(files) == 0 {\n\t\tt.Errorf(\"no test files found\")\n\t}\n\tfor _, file := range files {\n\t\tt.Run(filepath.Base(file), func(t *testing.T) {\n\t\t\ta, err := txtar.ParseFile(file)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to parse txtar file: %v\", err)\n\t\t\t}\n\t\t\tif len(a.Files) != 2 {\n\t\t\t\tt.Fatalf(\"expected 2 files, got %d\", len(a.Files))\n\t\t\t}\n\t\t\ttemplate, err := parser.ParseString(clean(a.Files[0].Data))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to parse %v\", err)\n\t\t\t}\n\t\t\ttemplate.Filepath = a.Files[0].Name\n\t\t\ttf, err := Process(template)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to process file: %v\", err)\n\t\t\t}\n\t\t\texpected := string(a.Files[1].Data)\n\t\t\tactual := new(strings.Builder)\n\t\t\tif err := tf.Write(actual); err != nil {\n\t\t\t\tt.Fatalf(\"failed to write template file: %v\", err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(expected, actual.String()); diff != \"\" {\n\t\t\t\tt.Errorf(\"%s:\\n%s\", file, diff)\n\t\t\t\tt.Errorf(\"expected:\\n%s\", showWhitespace(expected))\n\t\t\t\tt.Errorf(\"actual:\\n%s\", showWhitespace(actual.String()))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc showWhitespace(s string) string {\n\ts = strings.ReplaceAll(s, \"\\n\", \"⏎\\n\")\n\ts = strings.ReplaceAll(s, \"\\t\", \"→\")\n\ts = strings.ReplaceAll(s, \" \", \"·\")\n\treturn s\n}\n\nfunc clean(b []byte) string {\n\tb = bytes.ReplaceAll(b, []byte(\"$\\n\"), []byte(\"\\n\"))\n\tb = bytes.TrimSuffix(b, []byte(\"\\n\"))\n\treturn string(b)\n}\n\nfunc TestImport(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping test in short mode.\")\n\t\treturn\n\t}\n\n\ttests := []struct {\n\t\tname       string\n\t\tsrc        string\n\t\tassertions func(t *testing.T, updated string)\n\t}{\n\t\t{\n\t\t\tname: \"hyphenated imports are retained when used\",\n\t\t\tsrc: `package main\n\nimport \"fmt\"\nimport \"github.com/a-h/templ/cmd/templ/testproject/css-classes\"\n\ntempl Page(count int) {\n\t{ fmt.Sprintf(\"%d\", count) }\n\t{ cssclasses.Header }\n}\n`,\n\t\t\tassertions: func(t *testing.T, updated string) {\n\t\t\t\t// The import should be retained because cssclasses.Header uses it\n\t\t\t\t// It should either be unnamed or named (cssclasses)\n\t\t\t\tif count := strings.Count(updated, \"github.com/a-h/templ/cmd/templ/testproject/css-classes\"); count == 0 {\n\t\t\t\t\tt.Errorf(\"expected hyphenated import to be retained, but it was removed\")\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"named imports are retained\",\n\t\t\tsrc: `package main\n\nimport \"fmt\"\nimport  cssclasses \"github.com/a-h/templ/cmd/templ/testproject/css-classes\"\n\ntempl Page(count int) {\n\t{ fmt.Sprintf(\"%d\", count) }\n\t{ cssclasses.Header }\n}\n`,\n\t\t\tassertions: func(t *testing.T, updated string) {\n\t\t\t\tif count := strings.Count(updated, \"cssclasses \\\"github.com/a-h/templ/cmd/templ/testproject/css-classes\\\"\"); count != 1 {\n\t\t\t\t\tt.Errorf(\"expected named import to be retained, got %d instances of it\", count)\n\t\t\t\t}\n\t\t\t\tif count := strings.Count(updated, \"github.com/a-h/templ/cmd/templ/testproject/css-classes\"); count != 1 {\n\t\t\t\t\tt.Errorf(\"expected one import, got %d\", count)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t// Create test project.\n\t\t\tdir, err := testproject.Create(\"github.com/a-h/templ/cmd/templ/testproject\")\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to create test project: %v\", err)\n\t\t\t}\n\t\t\tdefer func() {\n\t\t\t\tif err = os.RemoveAll(dir); err != nil {\n\t\t\t\t\tt.Errorf(\"failed to remove test project directory: %v\", err)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\t// Load the templates.templ file.\n\t\t\tfilePath := path.Join(dir, \"templates.templ\")\n\t\t\terr = os.WriteFile(filePath, []byte(test.src), 0660)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to write file: %v\", err)\n\t\t\t}\n\n\t\t\t// Parse the new file.\n\t\t\ttemplate, err := parser.Parse(filePath)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to parse %v\", err)\n\t\t\t}\n\t\t\ttemplate.Filepath = filePath\n\t\t\ttf, err := Process(template)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to process file: %v\", err)\n\t\t\t}\n\n\t\t\t// Write it back out after processing.\n\t\t\tbuf := new(strings.Builder)\n\t\t\tif err := tf.Write(buf); err != nil {\n\t\t\t\tt.Fatalf(\"failed to write template file: %v\", err)\n\t\t\t}\n\n\t\t\t// Assert.\n\t\t\ttest.assertions(t, buf.String())\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/imports/testdata/comments.txtar",
    "content": "-- fmt_templ.templ --\npackage test\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(\"Hello\")\n-- fmt_templ.templ --\npackage test\n\nimport \"fmt\"\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(\"Hello\")\n"
  },
  {
    "path": "internal/imports/testdata/commentsbeforepackage.txtar",
    "content": "-- fmt_templ.templ --\n// Comments before.\n/*\n  Some more comments\n*/\npackage test\n\ntempl test() {\n  <div>Hello</div>\n}\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(\"Hello\")\n-- fmt_templ.templ --\n// Comments before.\n/*\n  Some more comments\n*/\npackage test\n\nimport \"fmt\"\n\ntempl test() {\n\t<div>Hello</div>\n}\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(\"Hello\")\n"
  },
  {
    "path": "internal/imports/testdata/deleteimports.txtar",
    "content": "-- fmt.templ --\npackage test\n\nimport \"strconv\"\n\ntempl Hello() {\n\t<div>Hello</div>\n}\n-- fmt.templ --\npackage test\n\ntempl Hello() {\n\t<div>Hello</div>\n}\n"
  },
  {
    "path": "internal/imports/testdata/extraspace.txtar",
    "content": "-- fmt_templ.templ --\npackage test\n\nconst x = 123\n\n\nvar x = fmt.Sprintf(\"Hello\")\n-- fmt_templ.templ --\npackage test\n\nimport \"fmt\"\n\nconst x = 123\n\nvar x = fmt.Sprintf(\"Hello\")\n"
  },
  {
    "path": "internal/imports/testdata/groups.txtar",
    "content": "-- fmt.templ --\npackage test\n\nimport (\n\t\"strings\"\n\t\"fmt\"\n\n\t\"strconv\"\n)\n\nvar _, _ = fmt.Print(strings.Contains(strconv.Quote(\"Hello\"), \"\"))\n-- fmt.templ --\npackage test\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"strconv\"\n)\n\nvar _, _ = fmt.Print(strings.Contains(strconv.Quote(\"Hello\"), \"\"))\n"
  },
  {
    "path": "internal/imports/testdata/groupsmanynewlines.txtar",
    "content": "-- fmt.templ --\npackage test\n\nimport (\n\t\"fmt\"\n\n\n\t\"strconv\"\n)\n\nvar _, _ = fmt.Print(strconv.Quote(\"Hello\"))\n-- fmt.templ --\npackage test\n\nimport (\n\t\"fmt\"\n\n\t\"strconv\"\n)\n\nvar _, _ = fmt.Print(strconv.Quote(\"Hello\"))\n"
  },
  {
    "path": "internal/imports/testdata/header.txtar",
    "content": "-- fmt_templ.templ --\npackage test\n\nvar x = fmt.Sprintf(\"Hello\")\n-- fmt_templ.templ --\npackage test\n\nimport \"fmt\"\n\nvar x = fmt.Sprintf(\"Hello\")\n"
  },
  {
    "path": "internal/imports/testdata/hyphenatedimport.txtar",
    "content": "-- fmt.templ --\npackage test\n\nimport \"github.com/a-h/templ/cmd/templ/testproject/css-classes\"\n\ntempl Hello() {\n\t{ cssclasses.Header }\n}\n-- fmt.templ --\npackage test\n\nimport \"github.com/a-h/templ/cmd/templ/testproject/css-classes\"\n\ntempl Hello() {\n\t{ cssclasses.Header }\n}\n"
  },
  {
    "path": "internal/imports/testdata/namedimportsadd.txtar",
    "content": "-- fmt_templ.templ --\npackage test\n\nimport (\n  sconv \"strconv\"\n)\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(sconv.Quote(\"Hello\"))\n-- fmt_templ.templ --\npackage test\n\nimport (\n\t\"fmt\"\n\tsconv \"strconv\"\n)\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(sconv.Quote(\"Hello\"))\n"
  },
  {
    "path": "internal/imports/testdata/namedimportsremoved.txtar",
    "content": "-- fmt_templ.templ --\npackage test\n\nimport (\n  sconv \"strconv\"\n)\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(\"Hello\")\n-- fmt_templ.templ --\npackage test\n\nimport \"fmt\"\n\n// Comment on variable or function.\nvar x = fmt.Sprintf(\"Hello\")\n"
  },
  {
    "path": "internal/imports/testdata/noimports.txtar",
    "content": "-- fmt.templ --\npackage test\n\ntempl Hello() {\n\t<div>Hello</div>\n}\n-- fmt.templ --\npackage test\n\ntempl Hello() {\n\t<div>Hello</div>\n}\n"
  },
  {
    "path": "internal/imports/testdata/noimportscode.txtar",
    "content": "-- fmt.templ --\npackage test\n\nfunc test() {\n  // Do nothing.\n}\n\ntempl Hello() {\n\t<div>Hello</div>\n}\n-- fmt.templ --\npackage test\n\nfunc test() {\n\t// Do nothing.\n}\n\ntempl Hello() {\n\t<div>Hello</div>\n}\n"
  },
  {
    "path": "internal/imports/testdata/stringexp.txtar",
    "content": "-- fmt.templ --\npackage test\n\ntempl Hello(name string) {\n\t{ fmt.Sprintf(\"Hello, %s!\", name) }\n}\n-- fmt.templ --\npackage test\n\nimport \"fmt\"\n\ntempl Hello(name string) {\n\t{ fmt.Sprintf(\"Hello, %s!\", name) }\n}\n"
  },
  {
    "path": "internal/imports/testdata/twoimports.txtar",
    "content": "-- fmt.templ --\npackage test\n\ntempl Hello(name string) {\n\t<div id={ strconv.Atoi(\"123\") }>\n\t\t{ fmt.Sprintf(\"Hello, %s!\", name) }\n\t</div>\n}\n-- fmt.templ --\npackage test\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\ntempl Hello(name string) {\n\t<div id={ strconv.Atoi(\"123\") }>\n\t\t{ fmt.Sprintf(\"Hello, %s!\", name) }\n\t</div>\n}\n"
  },
  {
    "path": "internal/lazyloader/docheader.go",
    "content": "package lazyloader\n\nimport (\n\t\"maps\"\n)\n\ntype docHeader interface {\n\tequal(other docHeader) bool\n}\n\ntype goDocHeader struct {\n\tpkgName string\n\timports map[string]struct{}\n}\n\nfunc (h *goDocHeader) equal(other docHeader) bool {\n\to, ok := other.(*goDocHeader)\n\tif !ok || o == nil {\n\t\treturn false\n\t}\n\n\tif h.pkgName != o.pkgName {\n\t\treturn false\n\t}\n\n\treturn maps.Equal(h.imports, o.imports)\n}\n"
  },
  {
    "path": "internal/lazyloader/docheader_test.go",
    "content": "package lazyloader\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestGoDocHeaderEqual(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\ta        *goDocHeader\n\t\tb        docHeader\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname: \"other header is not a goDocHeader\",\n\t\t\ta: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}},\n\t\t\t},\n\t\t\tb: mockDocHeader{},\n\t\t},\n\t\t{\n\t\t\tname: \"nil other header\",\n\t\t\ta: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}},\n\t\t\t},\n\t\t\tb: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"different package names\",\n\t\t\ta: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}},\n\t\t\t},\n\t\t\tb: &goDocHeader{\n\t\t\t\tpkgName: \"b\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"different number of imports\",\n\t\t\ta: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}, \"strings\": {}},\n\t\t\t},\n\t\t\tb: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"different import keys\",\n\t\t\ta: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}, \"bytes\": {}},\n\t\t\t},\n\t\t\tb: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\"fmt\": {}, \"strings\": {}},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"equal headers with same pkg and imports\",\n\t\t\ta: &goDocHeader{\n\t\t\t\tpkgName: \"mypkg\",\n\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\"fmt\":     {},\n\t\t\t\t\t\"strings\": {},\n\t\t\t\t},\n\t\t\t},\n\t\t\tb: &goDocHeader{\n\t\t\t\tpkgName: \"mypkg\",\n\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\"strings\": {},\n\t\t\t\t\t\"fmt\":     {},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tresult := tt.a.equal(tt.b)\n\t\t\tassert.Equal(t, tt.expected, result)\n\t\t})\n\t}\n}\n\ntype mockDocHeader struct{}\n\nfunc (m mockDocHeader) equal(_ docHeader) bool {\n\treturn false\n}\n"
  },
  {
    "path": "internal/lazyloader/docheaderparser.go",
    "content": "package lazyloader\n\nimport (\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/token\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\ntype docHeaderParser interface {\n\tparse(filename string) docHeader\n}\n\ntype goDocHeaderParser struct {\n\topenDocSources map[string]string\n\tfileParser     fileParser\n}\n\ntype fileParser interface {\n\tparseFile(fset *token.FileSet, file string, overlay any, mode parser.Mode) (*ast.File, error)\n}\n\ntype goFileParser struct{}\n\nfunc (goFileParser) parseFile(fset *token.FileSet, file string, overlay any, mode parser.Mode) (*ast.File, error) {\n\treturn parser.ParseFile(fset, file, overlay, mode)\n}\n\nfunc (p *goDocHeaderParser) parse(filename string) docHeader {\n\tvar overlay any\n\tfileURI := string(uri.File(filename))\n\tif source, ok := p.openDocSources[fileURI]; ok {\n\t\toverlay = source\n\t}\n\n\tfset := token.NewFileSet()\n\tfile, err := p.fileParser.parseFile(fset, filename, overlay, parser.ImportsOnly)\n\tif err != nil {\n\t\treturn &goDocHeader{}\n\t}\n\n\theader := &goDocHeader{\n\t\tpkgName: file.Name.Name,\n\t\timports: make(map[string]struct{}),\n\t}\n\n\tfor _, imp := range file.Imports {\n\t\theader.imports[imp.Path.Value] = struct{}{}\n\t}\n\n\treturn header\n}\n"
  },
  {
    "path": "internal/lazyloader/docheaderparser_test.go",
    "content": "package lazyloader\n\nimport (\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestGoDocHeaderParserParse(t *testing.T) {\n\ttests := []struct {\n\t\tname            string\n\t\tfilename        string\n\t\tparser          goDocHeaderParser\n\t\twantGoDocHeader *goDocHeader\n\t}{\n\t\t{\n\t\t\tname:     \"returns fallback header on parse error\",\n\t\t\tfilename: \"/bad.go\",\n\t\t\tparser: goDocHeaderParser{\n\t\t\t\topenDocSources: map[string]string{},\n\t\t\t\tfileParser: mockFileParser{\n\t\t\t\t\terr: assert.AnError,\n\t\t\t\t},\n\t\t\t},\n\t\t\twantGoDocHeader: &goDocHeader{},\n\t\t},\n\t\t{\n\t\t\tname:     \"returns header with no imports\",\n\t\t\tfilename: \"/no_imports.go\",\n\t\t\tparser: goDocHeaderParser{\n\t\t\t\topenDocSources: map[string]string{\n\t\t\t\t\t\"/no_imports.go\": \"package main\\n\\nfunc main() {}\\n\",\n\t\t\t\t},\n\t\t\t\tfileParser: mockFileParser{\n\t\t\t\t\tsource: map[string]string{\n\t\t\t\t\t\t\"/no_imports.go\": \"package main\\n\\nfunc main() {}\\n\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantGoDocHeader: &goDocHeader{\n\t\t\t\tpkgName: \"main\",\n\t\t\t\timports: map[string]struct{}{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:     \"returns header with imports\",\n\t\t\tfilename: \"/a.templ\",\n\t\t\tparser: goDocHeaderParser{\n\t\t\t\topenDocSources: map[string]string{\n\t\t\t\t\t\"/a.templ\": \"package a\\n\\nimport (\\n\\t\\\"strings\\\"\\n\\t\\\"fmt\\\"\\n)\\n\\nfunc main() {\\n}\\n\",\n\t\t\t\t},\n\t\t\t\tfileParser: mockFileParser{\n\t\t\t\t\tsource: map[string]string{\n\t\t\t\t\t\t\"/a.templ\": \"package a\\n\\nimport (\\n\\t\\\"strings\\\"\\n\\t\\\"fmt\\\"\\n)\\n\\nfunc main() {\\n}\\n\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantGoDocHeader: &goDocHeader{\n\t\t\t\tpkgName: \"a\",\n\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\"\\\"strings\\\"\": {},\n\t\t\t\t\t\"\\\"fmt\\\"\":     {},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:     \"reads overlay source\",\n\t\t\tfilename: \"/overlay.go\",\n\t\t\tparser: goDocHeaderParser{\n\t\t\t\topenDocSources: map[string]string{\n\t\t\t\t\t\"file:///overlay.go\": \"package overlay\\nfunc main() {}\",\n\t\t\t\t},\n\t\t\t\tfileParser: mockFileParser{\n\t\t\t\t\tsource: map[string]string{\n\t\t\t\t\t\t\"/overlay.go\": \"package overlay\\nfunc main() {}\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantGoDocHeader: &goDocHeader{\n\t\t\t\tpkgName: \"overlay\",\n\t\t\t\timports: map[string]struct{}{},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.parser.parse(tt.filename)\n\t\t\tassert.IsType(t, &goDocHeader{}, got)\n\t\t\th := got.(*goDocHeader)\n\t\t\tassert.Equal(t, tt.wantGoDocHeader.pkgName, h.pkgName)\n\t\t\tassert.Equal(t, tt.wantGoDocHeader.imports, h.imports)\n\t\t})\n\t}\n}\n\ntype mockFileParser struct {\n\tsource map[string]string\n\terr    error\n}\n\nfunc (m mockFileParser) parseFile(fset *token.FileSet, file string, _ any, mode parser.Mode) (*ast.File, error) {\n\tif m.err != nil {\n\t\treturn nil, m.err\n\t}\n\tcode, ok := m.source[file]\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\treturn parser.ParseFile(fset, file, code, mode)\n}\n"
  },
  {
    "path": "internal/lazyloader/pkgloader.go",
    "content": "package lazyloader\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"unsafe\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n\t\"golang.org/x/tools/go/packages\"\n)\n\nvar (\n\terrNoPkgsLoaded = errors.New(\"loaded no packages\")\n)\n\ntype pkgLoader interface {\n\tload(file string) (*packages.Package, error)\n}\n\ntype goPkgLoader struct {\n\topenDocSources map[string]string\n\tloadPackages   func(cfg *packages.Config, patterns ...string) ([]*packages.Package, error)\n}\n\nfunc (l *goPkgLoader) load(file string) (*packages.Package, error) {\n\tpkgs, err := l.loadPackages(\n\t\t&packages.Config{\n\t\t\tMode:    packages.NeedName | packages.NeedFiles | packages.NeedImports | packages.NeedDeps,\n\t\t\tOverlay: l.prepareOverlay(),\n\t\t},\n\t\t\"file=\"+file,\n\t)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(pkgs) == 0 {\n\t\treturn nil, errNoPkgsLoaded\n\t}\n\n\tif len(pkgs) > 1 {\n\t\treturn nil, fmt.Errorf(\"expected 1 package, loaded %d packages\", len(pkgs))\n\t}\n\n\treturn pkgs[0], nil\n}\n\nfunc (l *goPkgLoader) prepareOverlay() map[string][]byte {\n\toverlay := make(map[string][]byte, len(l.openDocSources))\n\tfor fileURI, source := range l.openDocSources {\n\t\toverlay[uri.New(fileURI).Filename()] = unsafe.Slice(unsafe.StringData(source), len(source))\n\t}\n\treturn overlay\n}\n"
  },
  {
    "path": "internal/lazyloader/pkgloader_test.go",
    "content": "package lazyloader\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"golang.org/x/tools/go/packages\"\n)\n\nfunc TestGoPkgLoaderLoad(t *testing.T) {\n\ttests := []struct {\n\t\tname            string\n\t\tfilename        string\n\t\tloader          goPkgLoader\n\t\twantPkg         *packages.Package\n\t\twantErrContains string\n\t}{\n\t\t{\n\t\t\tname:     \"loadPackages returns error\",\n\t\t\tfilename: \"/bad.go\",\n\t\t\tloader: goPkgLoader{\n\t\t\t\tloadPackages: func(cfg *packages.Config, patterns ...string) ([]*packages.Package, error) {\n\t\t\t\t\treturn nil, errors.New(\"load failed\")\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"load failed\",\n\t\t},\n\t\t{\n\t\t\tname:     \"returns multiple packages\",\n\t\t\tfilename: \"/multi.go\",\n\t\t\tloader: goPkgLoader{\n\t\t\t\tloadPackages: func(cfg *packages.Config, patterns ...string) ([]*packages.Package, error) {\n\t\t\t\t\treturn []*packages.Package{\n\t\t\t\t\t\t{Name: \"a\"},\n\t\t\t\t\t\t{Name: \"b\"},\n\t\t\t\t\t}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"expected 1 package, loaded 2 packages\",\n\t\t},\n\t\t{\n\t\t\tname:     \"returns zero packages\",\n\t\t\tfilename: \"/empty.go\",\n\t\t\tloader: goPkgLoader{\n\t\t\t\tloadPackages: func(cfg *packages.Config, patterns ...string) ([]*packages.Package, error) {\n\t\t\t\t\treturn []*packages.Package{}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"loaded no packages\",\n\t\t},\n\t\t{\n\t\t\tname:     \"returns package successfully\",\n\t\t\tfilename: \"/main.go\",\n\t\t\tloader: goPkgLoader{\n\t\t\t\topenDocSources: map[string]string{\n\t\t\t\t\t\"file:///main.go\": \"package main\\nfunc main() {}\",\n\t\t\t\t},\n\t\t\t\tloadPackages: func(cfg *packages.Config, patterns ...string) ([]*packages.Package, error) {\n\t\t\t\t\tassert.Equal(t, \"file=/main.go\", patterns[0])\n\t\t\t\t\tassert.NotNil(t, cfg.Overlay)\n\t\t\t\t\tcontent, ok := cfg.Overlay[\"/main.go\"]\n\t\t\t\t\tassert.True(t, ok)\n\t\t\t\t\tassert.Equal(t, string(content), \"package main\\nfunc main() {}\")\n\t\t\t\t\treturn []*packages.Package{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tName:    \"main\",\n\t\t\t\t\t\t\tPkgPath: \"example.com/main\",\n\t\t\t\t\t\t\tGoFiles: []string{\"/main.go\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, nil\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkg: &packages.Package{\n\t\t\t\tName:    \"main\",\n\t\t\t\tPkgPath: \"example.com/main\",\n\t\t\t\tGoFiles: []string{\"/main.go\"},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgotPkg, err := tt.loader.load(tt.filename)\n\n\t\t\tif tt.wantErrContains != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.ErrorContains(t, err, tt.wantErrContains)\n\t\t\t\tassert.Nil(t, gotPkg)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t\tassert.Equal(t, tt.wantPkg.Name, gotPkg.Name)\n\t\t\t\tassert.Equal(t, tt.wantPkg.PkgPath, gotPkg.PkgPath)\n\t\t\t\tassert.Equal(t, tt.wantPkg.GoFiles, gotPkg.GoFiles)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/lazyloader/pkgtraverser.go",
    "content": "package lazyloader\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n\t\"github.com/a-h/templ/lsp/uri\"\n\t\"golang.org/x/tools/go/packages\"\n)\n\nconst (\n\t_templExt = \".templ\"\n)\n\ntype pkgTraverser interface {\n\topenTopologically(ctx context.Context, pkg *packages.Package) error\n\tcloseTopologically(ctx context.Context, pkg *packages.Package) error\n}\n\ntype goPkgTraverser struct {\n\ttemplDocHandler TemplDocHandler\n\tpkgsRefCount    map[string]int\n\tfileReader      fileReader\n}\n\ntype TemplDocHandler interface {\n\tHandleDidOpen(ctx context.Context, params *lsp.DidOpenTextDocumentParams) error\n\tHandleDidClose(ctx context.Context, params *lsp.DidCloseTextDocumentParams) error\n}\n\ntype fileReader interface {\n\tread(file string) ([]byte, error)\n}\n\ntype templFileReader struct{}\n\nfunc (templFileReader) read(file string) ([]byte, error) {\n\treturn os.ReadFile(file)\n}\n\nfunc (t *goPkgTraverser) openTopologically(ctx context.Context, pkg *packages.Package) error {\n\tif t.pkgsRefCount[pkg.PkgPath] > 0 {\n\t\tt.pkgsRefCount[pkg.PkgPath]++\n\t\treturn nil\n\t}\n\n\tfor _, imp := range pkg.Imports {\n\t\tif err := t.openTopologically(ctx, imp); err != nil {\n\t\t\treturn fmt.Errorf(\"open topologically %q: %w\", imp.PkgPath, err)\n\t\t}\n\t}\n\n\tfor _, otherFile := range pkg.OtherFiles {\n\t\tif filepath.Ext(otherFile) != _templExt {\n\t\t\tcontinue\n\t\t}\n\n\t\ttext, err := t.fileReader.read(otherFile)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"read file %q: %w\", otherFile, err)\n\t\t}\n\n\t\tif err := t.templDocHandler.HandleDidOpen(ctx, &lsp.DidOpenTextDocumentParams{\n\t\t\tTextDocument: lsp.TextDocumentItem{\n\t\t\t\tURI:        uri.File(otherFile),\n\t\t\t\tText:       string(text),\n\t\t\t\tVersion:    1,\n\t\t\t\tLanguageID: \"go\",\n\t\t\t},\n\t\t}); err != nil {\n\t\t\treturn fmt.Errorf(\"did open file %q: %w\", otherFile, err)\n\t\t}\n\t}\n\tt.pkgsRefCount[pkg.PkgPath]++\n\n\treturn nil\n}\n\nfunc (t *goPkgTraverser) closeTopologically(ctx context.Context, pkg *packages.Package) error {\n\tif t.pkgsRefCount[pkg.PkgPath] > 1 {\n\t\tt.pkgsRefCount[pkg.PkgPath]--\n\t\treturn nil\n\t}\n\n\tfor _, otherFile := range pkg.OtherFiles {\n\t\tif filepath.Ext(otherFile) != _templExt {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := t.templDocHandler.HandleDidClose(ctx, &lsp.DidCloseTextDocumentParams{\n\t\t\tTextDocument: lsp.TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(otherFile),\n\t\t\t},\n\t\t}); err != nil {\n\t\t\treturn fmt.Errorf(\"did close file %q: %w\", otherFile, err)\n\t\t}\n\t}\n\tdelete(t.pkgsRefCount, pkg.PkgPath)\n\n\tfor _, imp := range pkg.Imports {\n\t\tif err := t.closeTopologically(ctx, imp); err != nil {\n\t\t\treturn fmt.Errorf(\"close topologically %q: %w\", imp.PkgPath, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "internal/lazyloader/pkgtraverser_test.go",
    "content": "package lazyloader\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/tools/go/packages\"\n)\n\nfunc TestTemplPkgTraverserOpenTopologically(t *testing.T) {\n\ttests := []struct {\n\t\tname             string\n\t\ttraverser        *goPkgTraverser\n\t\tpkg              *packages.Package\n\t\twantPkgsRefCount map[string]int\n\t\twantOpenedDocs   map[string]int\n\t\twantClosedDocs   map[string]int\n\t\twantErrContains  string\n\t}{\n\t\t{\n\t\t\tname: \"file read failed\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: assert.AnError},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tOtherFiles: []string{\"/foo.go\", \"/foo.templ\"},\n\t\t\t},\n\t\t\twantErrContains: \"read file \\\"/foo.templ\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"did open failed\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t\terror:      assert.AnError,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tOtherFiles: []string{\"/foo.go\", \"/foo.templ\"},\n\t\t\t},\n\t\t\twantErrContains: \"did open file \\\"/foo.templ\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"open a->b->c\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\", \"/a.go\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"a\": 1,\n\t\t\t\t\"b\": 1,\n\t\t\t\t\"c\": 1,\n\t\t\t},\n\t\t\twantOpenedDocs: map[string]int{\n\t\t\t\t\"/c.templ\":       1,\n\t\t\t\t\"/c_other.templ\": 1,\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"open a->b->c with c already open\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"c\": 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"a\": 1,\n\t\t\t\t\"b\": 1,\n\t\t\t\t\"c\": 2,\n\t\t\t},\n\t\t\twantOpenedDocs: map[string]int{\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"open a->b->c a->d->c\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"a\": 1,\n\t\t\t\t\"b\": 1,\n\t\t\t\t\"c\": 2,\n\t\t\t\t\"d\": 1,\n\t\t\t},\n\t\t\twantOpenedDocs: map[string]int{\n\t\t\t\t\"/d.templ\":       1,\n\t\t\t\t\"/c.templ\":       1,\n\t\t\t\t\"/c_other.templ\": 1,\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"open a->b->c a->d->c with d open\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"d\": 1,\n\t\t\t\t\t\"c\": 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"a\": 1,\n\t\t\t\t\"b\": 1,\n\t\t\t\t\"c\": 1,\n\t\t\t\t\"d\": 2,\n\t\t\t},\n\t\t\twantOpenedDocs: map[string]int{\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"open a->b->c a->d->c with a open\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"a\": 1,\n\t\t\t\t\t\"b\": 1,\n\t\t\t\t\t\"d\": 1,\n\t\t\t\t\t\"c\": 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"a\": 2,\n\t\t\t\t\"b\": 1,\n\t\t\t\t\"c\": 1,\n\t\t\t\t\"d\": 2,\n\t\t\t},\n\t\t\twantOpenedDocs: map[string]int{},\n\t\t},\n\t\t{\n\t\t\tname: \"open a->b->c a->d->c c->e with c open\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"c\": 1,\n\t\t\t\t\t\"e\": 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"e\": {\n\t\t\t\t\t\t\t\t\t\tPkgPath:    \"e\",\n\t\t\t\t\t\t\t\t\t\tOtherFiles: []string{\"/e.templ\"},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"e\": {\n\t\t\t\t\t\t\t\t\t\tPkgPath:    \"e\",\n\t\t\t\t\t\t\t\t\t\tOtherFiles: []string{\"/e.templ\"},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"a\": 1,\n\t\t\t\t\"b\": 1,\n\t\t\t\t\"c\": 3,\n\t\t\t\t\"d\": 1,\n\t\t\t\t\"e\": 1,\n\t\t\t},\n\t\t\twantOpenedDocs: map[string]int{\n\t\t\t\t\"/d.templ\":       1,\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\terr := tt.traverser.openTopologically(context.Background(), tt.pkg)\n\n\t\t\tif tt.wantErrContains != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.ErrorContains(t, err, tt.wantErrContains)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\n\t\t\t\thandler, ok := tt.traverser.templDocHandler.(*mockTemplDocHandler)\n\t\t\t\trequire.True(t, ok)\n\t\t\t\tassert.Equal(t, tt.wantOpenedDocs, handler.openedDocs)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTemplPkgTraverserCloseTopologically(t *testing.T) {\n\ttests := []struct {\n\t\tname             string\n\t\ttraverser        *goPkgTraverser\n\t\tpkg              *packages.Package\n\t\twantPkgsRefCount map[string]int\n\t\twantClosedDocs   map[string]int\n\t\twantErrContains  string\n\t}{\n\t\t{\n\t\t\tname: \"did close failed\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t\terror:      assert.AnError,\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\"foo\": 1},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"foo\",\n\t\t\t\tOtherFiles: []string{\"/foo.go\", \"/foo.templ\"},\n\t\t\t},\n\t\t\twantErrContains: \"did close file \\\"/foo.templ\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"close a->b->c\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"a\": 1, \"b\": 1, \"c\": 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\", \"/a.go\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{},\n\t\t\twantClosedDocs: map[string]int{\n\t\t\t\t\"/c.templ\":       1,\n\t\t\t\t\"/c_other.templ\": 1,\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"close a->b->c with c open\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"a\": 1, \"b\": 1, \"c\": 2,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\"c\": 1},\n\t\t\twantClosedDocs: map[string]int{\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"close a->b->c a->d->c\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"a\": 1, \"b\": 1, \"d\": 1, \"c\": 2,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{},\n\t\t\twantClosedDocs: map[string]int{\n\t\t\t\t\"/d.templ\":       1,\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t\t\"/c.templ\":       1,\n\t\t\t\t\"/c_other.templ\": 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"close a->b->c a->d->c with d open\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"a\": 1,\n\t\t\t\t\t\"b\": 1,\n\t\t\t\t\t\"c\": 2,\n\t\t\t\t\t\"d\": 2,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"c\": 1,\n\t\t\t\t\"d\": 1,\n\t\t\t},\n\t\t\twantClosedDocs: map[string]int{\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"close a->b->c a->d->c with a open\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"a\": 2,\n\t\t\t\t\t\"b\": 1,\n\t\t\t\t\t\"c\": 1,\n\t\t\t\t\t\"d\": 2,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"a\": 1,\n\t\t\t\t\"b\": 1,\n\t\t\t\t\"c\": 1,\n\t\t\t\t\"d\": 2,\n\t\t\t},\n\t\t\twantClosedDocs: map[string]int{},\n\t\t},\n\t\t{\n\t\t\tname: \"close a->b->c a->d->c c->e with c open twice\",\n\t\t\ttraverser: &goPkgTraverser{\n\t\t\t\tfileReader: mockFileReader{error: nil},\n\t\t\t\ttemplDocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t},\n\t\t\t\tpkgsRefCount: map[string]int{\n\t\t\t\t\t\"a\": 1,\n\t\t\t\t\t\"b\": 1,\n\t\t\t\t\t\"c\": 3,\n\t\t\t\t\t\"d\": 1,\n\t\t\t\t\t\"e\": 1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tpkg: &packages.Package{\n\t\t\t\tPkgPath:    \"a\",\n\t\t\t\tOtherFiles: []string{\"/a.templ\", \"/a_other.templ\"},\n\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\"b\": {\n\t\t\t\t\t\tPkgPath:    \"b\",\n\t\t\t\t\t\tOtherFiles: []string{\"/b.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"e\": {\n\t\t\t\t\t\t\t\t\t\tPkgPath:    \"e\",\n\t\t\t\t\t\t\t\t\t\tOtherFiles: []string{\"/e.templ\"},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tPkgPath:    \"d\",\n\t\t\t\t\t\tOtherFiles: []string{\"/d.templ\"},\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"c\": {\n\t\t\t\t\t\t\t\tPkgPath:    \"c\",\n\t\t\t\t\t\t\t\tOtherFiles: []string{\"/c.templ\", \"/c_other.templ\"},\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"e\": {\n\t\t\t\t\t\t\t\t\t\tPkgPath:    \"e\",\n\t\t\t\t\t\t\t\t\t\tOtherFiles: []string{\"/e.templ\"},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantPkgsRefCount: map[string]int{\n\t\t\t\t\"c\": 1,\n\t\t\t\t\"e\": 1,\n\t\t\t},\n\t\t\twantClosedDocs: map[string]int{\n\t\t\t\t\"/a.templ\":       1,\n\t\t\t\t\"/a_other.templ\": 1,\n\t\t\t\t\"/b.templ\":       1,\n\t\t\t\t\"/d.templ\":       1,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\terr := tt.traverser.closeTopologically(context.Background(), tt.pkg)\n\n\t\t\tif tt.wantErrContains != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.ErrorContains(t, err, tt.wantErrContains)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\n\t\t\t\thandler, ok := tt.traverser.templDocHandler.(*mockTemplDocHandler)\n\t\t\t\trequire.True(t, ok)\n\t\t\t\tassert.Equal(t, tt.wantClosedDocs, handler.closedDocs)\n\t\t\t\tassert.Equal(t, tt.wantPkgsRefCount, tt.traverser.pkgsRefCount)\n\t\t\t}\n\t\t})\n\t}\n}\n\ntype mockFileReader struct {\n\tbytes []byte\n\terror error\n}\n\nfunc (r mockFileReader) read(_ string) ([]byte, error) {\n\treturn r.bytes, r.error\n}\n\ntype mockTemplDocHandler struct {\n\topenedDocs map[string]int\n\tclosedDocs map[string]int\n\terror      error\n}\n\nfunc (h *mockTemplDocHandler) HandleDidOpen(_ context.Context, params *lsp.DidOpenTextDocumentParams) error {\n\th.openedDocs[params.TextDocument.URI.Filename()]++\n\treturn h.error\n}\n\nfunc (h *mockTemplDocHandler) HandleDidClose(_ context.Context, params *lsp.DidCloseTextDocumentParams) error {\n\th.closedDocs[params.TextDocument.URI.Filename()]++\n\treturn h.error\n}\n"
  },
  {
    "path": "internal/lazyloader/templdoclazyloader.go",
    "content": "package lazyloader\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n\t\"golang.org/x/tools/go/packages\"\n)\n\n// TemplDocLazyLoader lazily loads templ documents as necessary.\ntype TemplDocLazyLoader interface {\n\t// Load loads a templ document and its dependencies.\n\tLoad(ctx context.Context, params *lsp.DidOpenTextDocumentParams) error\n\n\t// Sync syncs the dependencies of a templ document using the changes made to the document.\n\tSync(ctx context.Context, params *lsp.DidChangeTextDocumentParams) error\n\n\t// Unload unloads a templ document and its dependencies.\n\tUnload(ctx context.Context, params *lsp.DidCloseTextDocumentParams) error\n\n\t// HasLoaded reports whether a templ document and its dependencies have been loaded.\n\tHasLoaded(doc lsp.TextDocumentIdentifier) bool\n}\n\n// templDocLazyLoader is a loader that uses the go/packages API to lazily load templ documents in the dependency graph.\ntype templDocLazyLoader struct {\n\tloadedPkgs      map[string]*packages.Package\n\topenDocHeaders  map[string]docHeader\n\tdocsPendingLoad map[string]struct{}\n\tpkgLoader       pkgLoader\n\tpkgTraverser    pkgTraverser\n\tdocHeaderParser docHeaderParser\n\tdocHandler      TemplDocHandler\n}\n\n// NewParams specifies the parameters necessary to create a new lazy loader.\ntype NewParams struct {\n\tTemplDocHandler TemplDocHandler\n\tOpenDocSources  map[string]string\n}\n\n// New creates a new lazy loader using the provided arguments.\nfunc New(params NewParams) TemplDocLazyLoader {\n\treturn &templDocLazyLoader{\n\t\tloadedPkgs:      make(map[string]*packages.Package),\n\t\topenDocHeaders:  make(map[string]docHeader),\n\t\tdocsPendingLoad: make(map[string]struct{}),\n\t\tpkgLoader: &goPkgLoader{\n\t\t\topenDocSources: params.OpenDocSources,\n\t\t\tloadPackages:   packages.Load,\n\t\t},\n\t\tpkgTraverser: &goPkgTraverser{\n\t\t\ttemplDocHandler: params.TemplDocHandler,\n\t\t\tpkgsRefCount:    make(map[string]int),\n\t\t\tfileReader:      templFileReader{},\n\t\t},\n\t\tdocHeaderParser: &goDocHeaderParser{\n\t\t\topenDocSources: params.OpenDocSources,\n\t\t\tfileParser:     goFileParser{},\n\t\t},\n\t\tdocHandler: params.TemplDocHandler,\n\t}\n}\n\n// Load loads all templ documents in the dependency graph topologically (dependencies are loaded before dependents).\nfunc (l *templDocLazyLoader) Load(ctx context.Context, params *lsp.DidOpenTextDocumentParams) error {\n\tfilename := params.TextDocument.URI.Filename()\n\n\tpkg, err := l.pkgLoader.load(filename)\n\tif err != nil {\n\t\tif errors.Is(err, errNoPkgsLoaded) {\n\t\t\tl.docsPendingLoad[filename] = struct{}{}\n\t\t\treturn l.docHandler.HandleDidOpen(ctx, params)\n\t\t}\n\t\treturn fmt.Errorf(\"load package for file %q: %w\", filename, err)\n\t}\n\n\tif err := l.pkgTraverser.openTopologically(ctx, pkg); err != nil {\n\t\treturn fmt.Errorf(\"open topologically %q: %w\", pkg.PkgPath, err)\n\t}\n\n\tl.loadedPkgs[pkg.PkgPath] = pkg\n\tl.openDocHeaders[filename] = l.docHeaderParser.parse(filename)\n\n\treturn nil\n}\n\n// Sync loads templ documents in newly added dependencies and unloads those that are no longer necessary.\nfunc (l *templDocLazyLoader) Sync(ctx context.Context, params *lsp.DidChangeTextDocumentParams) error {\n\tfilename := params.TextDocument.URI.Filename()\n\n\theader := l.openDocHeaders[filename]\n\tl.openDocHeaders[filename] = l.docHeaderParser.parse(filename)\n\tif l.openDocHeaders[filename].equal(header) {\n\t\treturn nil\n\t}\n\n\tpkg, err := l.pkgLoader.load(filename)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"load package for file %q: %w\", filename, err)\n\t}\n\tdelete(l.docsPendingLoad, filename)\n\n\tif _, ok := l.loadedPkgs[pkg.PkgPath]; !ok {\n\t\tif err := l.pkgTraverser.openTopologically(ctx, pkg); err != nil {\n\t\t\treturn fmt.Errorf(\"open topologically %q: %w\", pkg.PkgPath, err)\n\t\t}\n\t\tl.loadedPkgs[pkg.PkgPath] = pkg\n\n\t\treturn nil\n\t}\n\n\tfor _, imp := range pkg.Imports {\n\t\tif err := l.pkgTraverser.openTopologically(ctx, imp); err != nil {\n\t\t\treturn fmt.Errorf(\"open topologically %q: %w\", imp.PkgPath, err)\n\t\t}\n\t}\n\n\tfor _, imp := range l.loadedPkgs[pkg.PkgPath].Imports {\n\t\tif err := l.pkgTraverser.closeTopologically(ctx, imp); err != nil {\n\t\t\treturn fmt.Errorf(\"close topologically %q: %w\", imp.PkgPath, err)\n\t\t}\n\t}\n\tl.loadedPkgs[pkg.PkgPath] = pkg\n\n\treturn nil\n}\n\n// Unload unloads all templ documents in the dependency graph topologically (dependents are unloaded before dependencies).\nfunc (l *templDocLazyLoader) Unload(ctx context.Context, params *lsp.DidCloseTextDocumentParams) error {\n\tfilename := params.TextDocument.URI.Filename()\n\n\tpkg, err := l.pkgLoader.load(filename)\n\tif err != nil {\n\t\tif errors.Is(err, errNoPkgsLoaded) {\n\t\t\tdelete(l.docsPendingLoad, filename)\n\t\t\treturn l.docHandler.HandleDidClose(ctx, params)\n\t\t}\n\t\treturn fmt.Errorf(\"load package for file %q: %w\", filename, err)\n\t}\n\n\tif err := l.pkgTraverser.closeTopologically(ctx, pkg); err != nil {\n\t\treturn fmt.Errorf(\"close topologically %q: %w\", pkg.PkgPath, err)\n\t}\n\n\tdelete(l.loadedPkgs, pkg.PkgPath)\n\tdelete(l.openDocHeaders, filename)\n\n\treturn nil\n}\n\nfunc (l *templDocLazyLoader) HasLoaded(doc lsp.TextDocumentIdentifier) bool {\n\tif _, ok := l.docsPendingLoad[doc.URI.Filename()]; ok {\n\t\treturn false\n\t}\n\n\t_, ok := l.openDocHeaders[doc.URI.Filename()]\n\treturn ok\n}\n"
  },
  {
    "path": "internal/lazyloader/templdoclazyloader_test.go",
    "content": "package lazyloader\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"testing\"\n\n\tlsp \"github.com/a-h/templ/lsp/protocol\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/tools/go/packages\"\n)\n\nfunc TestTemplDocLazyLoaderLoad(t *testing.T) {\n\ttests := []struct {\n\t\tname                string\n\t\tloader              *templDocLazyLoader\n\t\tparams              *lsp.DidOpenTextDocumentParams\n\t\twantLoadedPkgs      map[string]*packages.Package\n\t\twantOpenDocHeaders  map[string]docHeader\n\t\twantDocsPendingLoad map[string]struct{}\n\t\twantErrContains     string\n\t}{\n\t\t{\n\t\t\tname: \"load package failed\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn nil, assert.AnError\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidOpenTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentItem{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"load package for file \\\"/foo.go\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"load package failed with no packages loaded\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn nil, errNoPkgsLoaded\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdocHandler: &mockTemplDocHandler{\n\t\t\t\t\topenedDocs: map[string]int{},\n\t\t\t\t\terror:      errors.New(\"mock error\"),\n\t\t\t\t},\n\t\t\t\tdocsPendingLoad: map[string]struct{}{},\n\t\t\t},\n\t\t\tparams: &lsp.DidOpenTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentItem{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantDocsPendingLoad: map[string]struct{}{\n\t\t\t\t\"/foo.go\": {},\n\t\t\t},\n\t\t\twantErrContains: \"mock error\",\n\t\t},\n\t\t{\n\t\t\tname: \"open topologically failed\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{{PkgPath: \"foo_pkg\"}}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{\n\t\t\t\t\topenErrors: map[string]error{\"foo_pkg\": assert.AnError},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidOpenTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentItem{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"open topologically \\\"foo_pkg\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"loaded successfully\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{{PkgPath: \"foo_pkg\"}}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{pkgName: \"foo_pkg\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tloadedPkgs:     map[string]*packages.Package{},\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t},\n\t\t\tparams: &lsp.DidOpenTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentItem{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantLoadedPkgs: map[string]*packages.Package{\n\t\t\t\t\"foo_pkg\": {PkgPath: \"foo_pkg\"},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{pkgName: \"foo_pkg\"},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\terr := tt.loader.Load(context.Background(), tt.params)\n\n\t\t\tif tt.wantErrContains != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.ErrorContains(t, err, tt.wantErrContains)\n\t\t\t\tassert.Equal(t, tt.wantDocsPendingLoad, tt.loader.docsPendingLoad)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t\tassert.Equal(t, tt.wantLoadedPkgs, tt.loader.loadedPkgs)\n\t\t\t\tassert.Equal(t, tt.wantOpenDocHeaders, tt.loader.openDocHeaders)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTemplDocLazyLoaderSync(t *testing.T) {\n\ttests := []struct {\n\t\tname                string\n\t\tloader              *templDocLazyLoader\n\t\tparams              *lsp.DidChangeTextDocumentParams\n\t\twantLoadedPkgs      map[string]*packages.Package\n\t\twantOpenDocHeaders  map[string]docHeader\n\t\twantOpenedPkgs      []string\n\t\twantClosedPkgs      []string\n\t\twantDocsPendingLoad map[string]struct{}\n\t\twantErrContains     string\n\t}{\n\t\t{\n\t\t\tname: \"same header\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{\n\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{},\n\t\t\t},\n\t\t\tparams: &lsp.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: lsp.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: lsp.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContentChanges: []lsp.TextDocumentContentChangeEvent{\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 11}, End: lsp.Position{Line: 22}}},\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 3}, End: lsp.Position{Line: 9}}},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"load package failed\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn nil, assert.AnError\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{},\n\t\t\t},\n\t\t\tparams: &lsp.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: lsp.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: lsp.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContentChanges: []lsp.TextDocumentContentChangeEvent{\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 11}, End: lsp.Position{Line: 22}}},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"load package for file \\\"/foo.go\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"open topologically failed when package never loaded\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"bar_pkg\": {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{\n\t\t\t\t\topenErrors: map[string]error{\"foo_pkg\": assert.AnError},\n\t\t\t\t},\n\t\t\t\tloadedPkgs: map[string]*packages.Package{},\n\t\t\t},\n\t\t\tparams: &lsp.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: lsp.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: lsp.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContentChanges: []lsp.TextDocumentContentChangeEvent{\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 11}, End: lsp.Position{Line: 22}}},\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 3}, End: lsp.Position{Line: 9}}},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"open topologically \\\"foo_pkg\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"successfully loaded package when never loaded\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"bar_pkg\": {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{\n\t\t\t\t\topenErrors: map[string]error{},\n\t\t\t\t},\n\t\t\t\tloadedPkgs: map[string]*packages.Package{},\n\t\t\t\tdocsPendingLoad: map[string]struct{}{\n\t\t\t\t\t\"/foo.go\": {},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: lsp.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: lsp.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContentChanges: []lsp.TextDocumentContentChangeEvent{\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 11}, End: lsp.Position{Line: 22}}},\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 3}, End: lsp.Position{Line: 9}}},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantLoadedPkgs: map[string]*packages.Package{\n\t\t\t\t\"foo_pkg\": {\n\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\"bar_pkg\": {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenedPkgs:      []string{\"foo_pkg\"},\n\t\t\twantDocsPendingLoad: map[string]struct{}{},\n\t\t},\n\t\t{\n\t\t\tname: \"open topologically failed\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"bar_pkg\": {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{\n\t\t\t\t\topenErrors: map[string]error{\"bar_pkg\": assert.AnError},\n\t\t\t\t},\n\t\t\t\tloadedPkgs: map[string]*packages.Package{\n\t\t\t\t\t\"foo_pkg\": {\n\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"bar_pkg\": {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: lsp.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: lsp.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContentChanges: []lsp.TextDocumentContentChangeEvent{\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 11}, End: lsp.Position{Line: 22}}},\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 3}, End: lsp.Position{Line: 9}}},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"open topologically \\\"bar_pkg\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"close topologically failed\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{\n\t\t\t\t\tcloseErrors: map[string]error{\"bar_pkg\": assert.AnError},\n\t\t\t\t},\n\t\t\t\tloadedPkgs: map[string]*packages.Package{\n\t\t\t\t\t\"foo_pkg\": {\n\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"bar_pkg\": {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: lsp.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: lsp.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContentChanges: []lsp.TextDocumentContentChangeEvent{\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 11}, End: lsp.Position{Line: 22}}},\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 3}, End: lsp.Position{Line: 9}}},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"close topologically \\\"bar_pkg\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"synced successfully\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\t\t\"bar_pkg\":    {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t\t\t\t\"foobar_pkg\": {PkgPath: \"foobar_pkg\"},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{},\n\t\t\t\tloadedPkgs: map[string]*packages.Package{\n\t\t\t\t\t\"foo_pkg\": {\n\t\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\t\"bar_pkg\":    {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t\t\"barfoo_pkg\": {PkgPath: \"barfoo_pkg\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidChangeTextDocumentParams{\n\t\t\t\tTextDocument: lsp.VersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: lsp.TextDocumentIdentifier{\n\t\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContentChanges: []lsp.TextDocumentContentChangeEvent{\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 11}, End: lsp.Position{Line: 22}}},\n\t\t\t\t\t{Range: &lsp.Range{Start: lsp.Position{Line: 3}, End: lsp.Position{Line: 9}}},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantLoadedPkgs: map[string]*packages.Package{\n\t\t\t\t\"foo_pkg\": {\n\t\t\t\t\tPkgPath: \"foo_pkg\",\n\t\t\t\t\tImports: map[string]*packages.Package{\n\t\t\t\t\t\t\"bar_pkg\":    {PkgPath: \"bar_pkg\"},\n\t\t\t\t\t\t\"foobar_pkg\": {PkgPath: \"foobar_pkg\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenDocHeaders: map[string]docHeader{\n\t\t\t\t\"/foo.go\": &goDocHeader{\n\t\t\t\t\tpkgName: \"foo_pkg\",\n\t\t\t\t\timports: map[string]struct{}{\n\t\t\t\t\t\t\"fmt\": {},\n\t\t\t\t\t\t\"os\":  {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantOpenedPkgs: []string{\"bar_pkg\", \"foobar_pkg\"},\n\t\t\twantClosedPkgs: []string{\"bar_pkg\", \"barfoo_pkg\"},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\terr := tt.loader.Sync(context.Background(), tt.params)\n\n\t\t\tif tt.wantErrContains != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.ErrorContains(t, err, tt.wantErrContains)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t\tassert.Equal(t, tt.wantLoadedPkgs, tt.loader.loadedPkgs)\n\t\t\t\tassert.Equal(t, tt.wantOpenDocHeaders, tt.loader.openDocHeaders)\n\t\t\t\tassert.Equal(t, tt.wantDocsPendingLoad, tt.loader.docsPendingLoad)\n\n\t\t\t\ttraverser, ok := tt.loader.pkgTraverser.(*mockPkgTraverser)\n\t\t\t\trequire.True(t, ok)\n\t\t\t\tassert.ElementsMatch(t, tt.wantOpenedPkgs, traverser.openedPkgs)\n\t\t\t\tassert.ElementsMatch(t, tt.wantClosedPkgs, traverser.closedPkgs)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTemplDocLazyLoaderUnload(t *testing.T) {\n\ttests := []struct {\n\t\tname                string\n\t\tloader              *templDocLazyLoader\n\t\tparams              *lsp.DidCloseTextDocumentParams\n\t\twantLoadedPkgs      map[string]*packages.Package\n\t\twantOpenDocHeaders  map[string]docHeader\n\t\twantDocsPendingLoad map[string]struct{}\n\t\twantErrContains     string\n\t}{\n\t\t{\n\t\t\tname: \"load package failed\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn nil, assert.AnError\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidCloseTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentIdentifier{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"load package for file \\\"/foo.go\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"load package failed with no packages loaded\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn nil, errNoPkgsLoaded\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdocHandler: &mockTemplDocHandler{\n\t\t\t\t\tclosedDocs: map[string]int{},\n\t\t\t\t\terror:      errors.New(\"mock error\"),\n\t\t\t\t},\n\t\t\t\tdocsPendingLoad: map[string]struct{}{\n\t\t\t\t\t\"/foo.go\": {},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidCloseTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentIdentifier{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantDocsPendingLoad: map[string]struct{}{},\n\t\t\twantErrContains:     \"mock error\",\n\t\t},\n\t\t{\n\t\t\tname: \"close topologically failed\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{{PkgPath: \"foo_pkg\"}}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{\n\t\t\t\t\tcloseErrors: map[string]error{\"foo_pkg\": assert.AnError},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidCloseTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentIdentifier{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErrContains: \"close topologically \\\"foo_pkg\\\"\",\n\t\t},\n\t\t{\n\t\t\tname: \"unloaded successfully\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tpkgLoader: &goPkgLoader{\n\t\t\t\t\tloadPackages: func(_ *packages.Config, _ ...string) ([]*packages.Package, error) {\n\t\t\t\t\t\treturn []*packages.Package{{PkgPath: \"foo_pkg\"}}, nil\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpkgTraverser: &mockPkgTraverser{},\n\t\t\t\tdocHeaderParser: &mockDocHeaderParser{\n\t\t\t\t\theaders: map[string]docHeader{\n\t\t\t\t\t\t\"/foo.go\": &goDocHeader{pkgName: \"foo_pkg\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tloadedPkgs: map[string]*packages.Package{\n\t\t\t\t\t\"foo_pkg\": {PkgPath: \"foo_pkg\"},\n\t\t\t\t},\n\t\t\t\topenDocHeaders: map[string]docHeader{\n\t\t\t\t\t\"/foo.go\": &goDocHeader{pkgName: \"foo_pkg\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\tparams: &lsp.DidCloseTextDocumentParams{\n\t\t\t\tTextDocument: lsp.TextDocumentIdentifier{\n\t\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantLoadedPkgs:     map[string]*packages.Package{},\n\t\t\twantOpenDocHeaders: map[string]docHeader{},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\terr := tt.loader.Unload(context.Background(), tt.params)\n\n\t\t\tif tt.wantErrContains != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.ErrorContains(t, err, tt.wantErrContains)\n\t\t\t\tassert.Equal(t, tt.wantDocsPendingLoad, tt.loader.docsPendingLoad)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t\tassert.Equal(t, tt.wantLoadedPkgs, tt.loader.loadedPkgs)\n\t\t\t\tassert.Equal(t, tt.wantOpenDocHeaders, tt.loader.openDocHeaders)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTemplDocLazyLoaderHasLoaded(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tloader   *templDocLazyLoader\n\t\tdoc      lsp.TextDocumentIdentifier\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname: \"doc pending load\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\tdocsPendingLoad: map[string]struct{}{\n\t\t\t\t\t\"/foo.go\": {},\n\t\t\t\t},\n\t\t\t},\n\t\t\tdoc: lsp.TextDocumentIdentifier{\n\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"doc loaded\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{\n\t\t\t\t\t\"/foo.go\": &goDocHeader{pkgName: \"foo_pkg\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\tdoc: lsp.TextDocumentIdentifier{\n\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname: \"doc not loaded\",\n\t\t\tloader: &templDocLazyLoader{\n\t\t\t\topenDocHeaders: map[string]docHeader{},\n\t\t\t},\n\t\t\tdoc: lsp.TextDocumentIdentifier{\n\t\t\t\tURI: lsp.DocumentURI(\"file:///foo.go\"),\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tassert.Equal(t, tt.expected, tt.loader.HasLoaded(tt.doc))\n\t\t})\n\t}\n}\n\ntype mockPkgTraverser struct {\n\topenedPkgs  []string\n\tclosedPkgs  []string\n\topenErrors  map[string]error\n\tcloseErrors map[string]error\n}\n\nfunc (t *mockPkgTraverser) openTopologically(_ context.Context, pkg *packages.Package) error {\n\terr, ok := t.openErrors[pkg.PkgPath]\n\tif !ok {\n\t\tt.openedPkgs = append(t.openedPkgs, pkg.PkgPath)\n\t}\n\treturn err\n}\n\nfunc (t *mockPkgTraverser) closeTopologically(_ context.Context, pkg *packages.Package) error {\n\terr, ok := t.closeErrors[pkg.PkgPath]\n\tif !ok {\n\t\tt.closedPkgs = append(t.closedPkgs, pkg.PkgPath)\n\t}\n\treturn err\n}\n\ntype mockDocHeaderParser struct {\n\theaders map[string]docHeader\n}\n\nfunc (p *mockDocHeaderParser) parse(filename string) docHeader {\n\treturn p.headers[filename]\n}\n"
  },
  {
    "path": "internal/prettier/prettier.go",
    "content": "package prettier\n\nimport (\n\t\"fmt\"\n\t\"html\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/a-h/templ/internal/htmlfind\"\n)\n\nconst defaultPosixCommand = \"prettier --use-tabs --stdin-filepath $TEMPL_PRETTIER_FILENAME\"\n\nvar shellNameToCommand = map[string]string{\n\t\"nu\": \"prettier --use-tabs --stdin-filepath $env.TEMPL_PRETTIER_FILENAME\",\n}\n\n// DefaultCommand returns the default prettier command appropriate for the current shell.\nfunc DefaultCommand() string {\n\tshell := os.Getenv(\"SHELL\")\n\tif shell == \"\" {\n\t\tshell = \"/bin/sh\"\n\t}\n\tshellName := filepath.Base(shell)\n\tif shellCommand, ok := shellNameToCommand[shellName]; ok {\n\t\treturn shellCommand\n\t}\n\treturn defaultPosixCommand\n}\n\nfunc IsAvailable(command string) bool {\n\texecutable := strings.Fields(command)[0]\n\t_, err := exec.LookPath(executable)\n\treturn err == nil\n}\n\n// Run the prettier command with the given input and file name.\n// $TEMPL_PRETTIER_FILENAME is set to the file name being formatted.\n// To format blocks inside templ files a fake name is provided, e.g. format.html, format.js, format.css etc.\n// The command is run in a shell, so it can be a complex command with pipes and redirections.\n//\n// Examples:\n//\n//\tprettier --use-tabs --stdin-filepath $TEMPL_PRETTIER_FILENAME\n//\tprettierd --use-tabs --stdin-filepath $TEMPL_PRETTIER_FILENAME\n//\tnpx prettier --use-tabs --stdin-filepath $TEMPL_PRETTIER_FILENAME\n//\tprettier --config ./frontend/.prettierrc --use-tabs --stdin-filepath $TEMPL_PRETTIER_FILENAME\nfunc Run(input, fileName, command string) (formatted string, err error) {\n\tcmd := getCommand(runtime.GOOS, os.Getenv(\"SHELL\"), command)\n\tcmd.Env = append(os.Environ(), fmt.Sprintf(\"TEMPL_PRETTIER_FILENAME=%s\", fileName))\n\tcmd.Stdin = strings.NewReader(input)\n\toutput, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to format with command %q, output: %q, error: %v\", cmd.Args, string(output), err)\n\t}\n\treturn string(output), nil\n}\n\nfunc getCommand(goos, shell, command string) *exec.Cmd {\n\tif shell == \"\" {\n\t\tshell = \"/bin/sh\"\n\t}\n\tif goos == \"windows\" {\n\t\treturn exec.Command(\"cmd.exe\", \"/C\", command)\n\t}\n\treturn exec.Command(shell, \"-c\", command)\n}\n\nfunc Element(name string, typeAttrValue string, content string, depth int, prettierCommand string) (after string, err error) {\n\tvar indentationWrapper strings.Builder\n\n\t// Add divs to the start and end of the script to ensure that prettier formats the content with\n\t// correct indentation.\n\tfor i := range depth {\n\t\tindentationWrapper.WriteString(fmt.Sprintf(\"<div data-templ-depth=\\\"%d\\\">\", i))\n\t}\n\n\t// Write start tag with type attribute if present.\n\tindentationWrapper.WriteString(\"<\")\n\tindentationWrapper.WriteString(name)\n\tif typeAttrValue != \"\" {\n\t\tindentationWrapper.WriteString(\" type=\\\"\")\n\t\tindentationWrapper.WriteString(html.EscapeString(typeAttrValue))\n\t\tindentationWrapper.WriteString(\"\\\"\")\n\t}\n\tindentationWrapper.WriteString(\">\")\n\n\t// Write contents.\n\tindentationWrapper.WriteString(content)\n\n\t// Write end tag.\n\tindentationWrapper.WriteString(\"</\")\n\tindentationWrapper.WriteString(name)\n\tindentationWrapper.WriteString(\">\")\n\n\tfor range depth {\n\t\tindentationWrapper.WriteString(\"</div>\")\n\t}\n\n\tbefore := indentationWrapper.String()\n\tafter, err = Run(before, \"templ_content.html\", prettierCommand)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"prettier error: %w\", err)\n\t}\n\tif before == after {\n\t\treturn before, nil\n\t}\n\n\t// Chop off the start and end divs we added to get prettier to format the content with correct\n\t// indentation.\n\tmatcher := htmlfind.Element(name)\n\tnodes, err := htmlfind.AllReader(strings.NewReader(after), matcher)\n\tif err != nil {\n\t\treturn before, fmt.Errorf(\"htmlfind error: %w\", err)\n\t}\n\tif len(nodes) != 1 {\n\t\treturn before, fmt.Errorf(\"expected 1 %q node, got %d\", name, len(nodes))\n\t}\n\tscriptNode := nodes[0]\n\tif scriptNode.FirstChild == nil {\n\t\treturn before, fmt.Errorf(\"%q node has no children\", name)\n\t}\n\tvar sb strings.Builder\n\tfor node := range scriptNode.ChildNodes() {\n\t\tsb.WriteString(node.Data)\n\t}\n\tafter = strings.TrimRight(sb.String(), \" \\t\\r\\n\") + \"\\n\" + strings.Repeat(\"\\t\", depth)\n\n\treturn after, nil\n}\n"
  },
  {
    "path": "internal/prettier/prettier_test.go",
    "content": "package prettier\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"golang.org/x/tools/txtar\"\n)\n\nfunc Test(t *testing.T) {\n\tarchive, err := txtar.ParseFile(\"testdata.txtar\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read testdata.txtar: %v\", err)\n\t}\n\tfor i := 0; i < len(archive.Files)-1; i += 2 {\n\t\tif archive.Files[i].Name != archive.Files[i+1].Name {\n\t\t\tt.Fatalf(\"test archive is not in the expected format: file pair at index %d do not match: %q vs %q\", i, archive.Files[i].Name, archive.Files[i+1].Name)\n\t\t}\n\t\tt.Run(archive.Files[i].Name, func(t *testing.T) {\n\t\t\tinputData := archive.Files[i].Data\n\t\t\texpectedData := archive.Files[i+1].Data\n\t\t\tinput := strings.TrimSpace(string(inputData))\n\t\t\texpected := strings.TrimSpace(string(expectedData))\n\t\t\tactual, err := Run(input, archive.Files[i].Name, DefaultCommand())\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif strings.TrimSpace(actual) != expected {\n\t\t\t\tt.Errorf(\"Actual:\\n%s\\nExpected:\\n%s\", actual, expected)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsAvailable(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"Skipping IsAvailable test in short mode\")\n\t}\n\tt.Run(\"non-existent commands return false\", func(t *testing.T) {\n\t\tvar nonExistentCommand = \"templ_non_existent_command --use-tabs --stdin-filepath $TEMPL_PRETTIER_FILENAME\"\n\t\tif IsAvailable(nonExistentCommand) {\n\t\t\tt.Errorf(\"IsAvailable should return false for non-existent command %q\", nonExistentCommand)\n\t\t}\n\t})\n\tt.Run(\"existing commands return true\", func(t *testing.T) {\n\t\tif !IsAvailable(\"ls -lah\") {\n\t\t\tt.Errorf(\"IsAvailable should return true for existing command %q\", DefaultCommand())\n\t\t}\n\t})\n}\n\nfunc TestGetCommand(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tgoos     string\n\t\tshell    string\n\t\tcommand  string\n\t\twantPath string\n\t\twantArgs []string\n\t}{\n\t\t{\n\t\t\tname:     \"nushell uses a custom command\",\n\t\t\tgoos:     \"linux\",\n\t\t\tshell:    \"/usr/bin/nu\",\n\t\t\tcommand:  shellNameToCommand[\"nu\"],\n\t\t\twantPath: \"/usr/bin/nu\",\n\t\t\twantArgs: []string{\"/usr/bin/nu\", \"-c\", shellNameToCommand[\"nu\"]},\n\t\t},\n\t\t{\n\t\t\tname:     \"bash uses the default posix command\",\n\t\t\tgoos:     \"linux\",\n\t\t\tshell:    \"/bin/bash\",\n\t\t\tcommand:  defaultPosixCommand,\n\t\t\twantPath: \"/bin/bash\",\n\t\t\twantArgs: []string{\"/bin/bash\", \"-c\", defaultPosixCommand},\n\t\t},\n\t\t{\n\t\t\tname:     \"zsh uses the default posix command\",\n\t\t\tgoos:     \"linux\",\n\t\t\tshell:    \"/bin/zsh\",\n\t\t\tcommand:  defaultPosixCommand,\n\t\t\twantPath: \"/bin/zsh\",\n\t\t\twantArgs: []string{\"/bin/zsh\", \"-c\", defaultPosixCommand},\n\t\t},\n\t\t{\n\t\t\tname:     \"empty shell defaults to the default posix command\",\n\t\t\tgoos:     \"linux\",\n\t\t\tshell:    \"\",\n\t\t\tcommand:  defaultPosixCommand,\n\t\t\twantPath: \"/bin/sh\",\n\t\t\twantArgs: []string{\"/bin/sh\", \"-c\", defaultPosixCommand},\n\t\t},\n\t\t{\n\t\t\tname:     \"windows uses cmd.exe regardless of shell\",\n\t\t\tgoos:     \"windows\",\n\t\t\tshell:    \"C:\\\\Program Files\\\\PowerShell\\\\pwsh.exe\",\n\t\t\tcommand:  \"prettier --stdin-filepath test.html\",\n\t\t\twantPath: \"cmd.exe\",\n\t\t\twantArgs: []string{\"cmd.exe\", \"/C\", \"prettier --stdin-filepath test.html\"},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tcmd := getCommand(tt.goos, tt.shell, tt.command)\n\t\t\tif cmd.Path != tt.wantPath {\n\t\t\t\tt.Errorf(\"got path %q, want %q\", cmd.Path, tt.wantPath)\n\t\t\t}\n\t\t\tif len(cmd.Args) != len(tt.wantArgs) {\n\t\t\t\tt.Errorf(\"got %d args, want %d\", len(cmd.Args), len(tt.wantArgs))\n\t\t\t}\n\t\t\tfor i, arg := range cmd.Args {\n\t\t\t\tif i < len(tt.wantArgs) && arg != tt.wantArgs[i] {\n\t\t\t\t\tt.Errorf(\"arg %d: got %q, want %q\", i, arg, tt.wantArgs[i])\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/prettier/testdata.txtar",
    "content": "-- js-1.js --\nfunction foo(){return 1;}\n-- js-1.js --\nfunction foo() {\n\treturn 1;\n}\n-- css-1.css --\nbody{color:red;}\n-- css-1.css --\nbody {\n\tcolor: red;\n}\n"
  },
  {
    "path": "internal/skipdir/skipdir.go",
    "content": "package skipdir\n\nimport (\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nfunc ShouldSkip(path string) (skip bool) {\n\tif path == \".\" {\n\t\treturn false\n\t}\n\t_, name := filepath.Split(path)\n\tif name == \"vendor\" || name == \"node_modules\" {\n\t\treturn true\n\t}\n\tif strings.HasPrefix(name, \".\") || strings.HasPrefix(name, \"_\") {\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "internal/skipdir/skipdir_test.go",
    "content": "package skipdir\n\nimport \"testing\"\n\nfunc TestSkipDir(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tdir      string\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"current directory is not skipped\",\n\t\t\tdir:      \".\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"standard paths are not skipped\",\n\t\t\tdir:      \"/home/user/adrian/github.com/a-h/templ/examples\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"vendor directories are skipped\",\n\t\t\tdir:      \"/home/user/adrian/github.com/a-h/templ/examples/vendor\",\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"node_modules directories are skipped\",\n\t\t\tdir:      \"/home/user/adrian/github.com/a-h/templ/examples/node_modules\",\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"dot directories are skipped\",\n\t\t\tdir:      \"/home/user/adrian/github.com/a-h/templ/examples/.git\",\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"underscore directories are skipped\",\n\t\t\tdir:      \"/home/user/adrian/github.com/a-h/templ/examples/_build\",\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"relative paths are normalised\",\n\t\t\tdir:      \"examples\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"relative paths are normalised\",\n\t\t\tdir:      \"examples/vendor\",\n\t\t\texpected: true,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tactual := ShouldSkip(test.dir)\n\t\t\tif test.expected != actual {\n\t\t\t\tt.Errorf(\"expected %v, got %v\", test.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/syncmap/map.go",
    "content": "package syncmap\n\nimport \"sync\"\n\nfunc New[K comparable, V any]() *Map[K, V] {\n\treturn &Map[K, V]{\n\t\tm:  make(map[K]V),\n\t\tmu: sync.RWMutex{},\n\t}\n}\n\ntype Map[K comparable, V any] struct {\n\tm  map[K]V\n\tmu sync.RWMutex\n}\n\nfunc (m *Map[K, V]) Get(key K) (v V, ok bool) {\n\tm.mu.RLock()\n\tdefer m.mu.RUnlock()\n\tv, ok = m.m[key]\n\treturn v, ok\n}\n\nfunc (m *Map[K, V]) Set(key K, value V) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tm.m[key] = value\n}\n\nfunc (m *Map[K, V]) Delete(key K) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tdelete(m.m, key)\n}\n\nfunc (m *Map[K, V]) CompareAndSwap(key K, shouldUpdate func(previous, updated V) bool, value V) (swapped bool) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tv, ok := m.m[key]\n\tif ok && !shouldUpdate(v, value) {\n\t\treturn false\n\t}\n\tm.m[key] = value\n\treturn true\n}\n\nfunc UpdateIfChanged[V comparable](previous, updated V) bool {\n\treturn previous != updated\n}\n"
  },
  {
    "path": "internal/syncmap/map_test.go",
    "content": "package syncmap\n\nimport \"testing\"\n\nfunc TestMap(t *testing.T) {\n\tt.Parallel()\n\tt.Run(\"Can Set and Get values\", func(t *testing.T) {\n\t\tm := New[string, int]()\n\t\tm.Set(\"key1\", 42)\n\t\tif v, ok := m.Get(\"key1\"); !ok || v != 42 {\n\t\t\tt.Errorf(\"Expected value 42 for key 'key1', got %d\", v)\n\t\t}\n\t})\n\tt.Run(\"Can Delete values\", func(t *testing.T) {\n\t\tm := New[string, int]()\n\t\tm.Set(\"key1\", 42)\n\t\tm.Delete(\"key1\")\n\t\tif _, ok := m.Get(\"key1\"); ok {\n\t\t\tt.Error(\"Expected key 'key1' to be deleted\")\n\t\t}\n\t})\n\tt.Run(\"CompareAndSwap\", func(t *testing.T) {\n\t\tt.Run(\"Swaps if condition is met\", func(t *testing.T) {\n\t\t\tm := New[string, int]()\n\t\t\tm.Set(\"key1\", 42)\n\t\t\tswapped := m.CompareAndSwap(\"key1\", func(previous, updated int) bool {\n\t\t\t\treturn updated > previous\n\t\t\t}, 50)\n\t\t\tif !swapped {\n\t\t\t\tt.Error(\"Expected CompareAndSwap to succeed\")\n\t\t\t}\n\t\t\tif v, ok := m.Get(\"key1\"); !ok || v != 50 {\n\t\t\t\tt.Errorf(\"Expected value 50 for key 'key1', got %d\", v)\n\t\t\t}\n\t\t})\n\t\tt.Run(\"Does not swap value if condition is not met\", func(t *testing.T) {\n\t\t\tm := New[string, int]()\n\t\t\tm.Set(\"key1\", 42)\n\t\t\tswapped := m.CompareAndSwap(\"key1\", func(previous, updated int) bool {\n\t\t\t\treturn updated > previous\n\t\t\t}, 30)\n\t\t\tif swapped {\n\t\t\t\tt.Error(\"Expected CompareAndSwap to fail\")\n\t\t\t}\n\t\t\tif v, ok := m.Get(\"key1\"); !ok || v != 42 {\n\t\t\t\tt.Errorf(\"Expected value 42 for key 'key1', got %d\", v)\n\t\t\t}\n\t\t})\n\t\tt.Run(\"Swaps value if it does not exist\", func(t *testing.T) {\n\t\t\tm := New[string, int]()\n\t\t\tswapped := m.CompareAndSwap(\"key1\", func(previous, updated int) bool {\n\t\t\t\treturn previous < updated\n\t\t\t}, 50)\n\t\t\tif !swapped {\n\t\t\t\tt.Error(\"Expected CompareAndSwap to succeed for non-existing key\")\n\t\t\t}\n\t\t\tif v, ok := m.Get(\"key1\"); !ok || v != 50 {\n\t\t\t\tt.Errorf(\"Expected value 50 for key 'key1', got %d\", v)\n\t\t\t}\n\t\t})\n\t\tt.Run(\"UpdateIfChanged\", func(t *testing.T) {\n\t\t\tt.Run(\"Swaps if the value is different\", func(t *testing.T) {\n\t\t\t\tm := New[string, int]()\n\t\t\t\tm.Set(\"key1\", 42)\n\t\t\t\tswapped := m.CompareAndSwap(\"key1\", UpdateIfChanged, 50)\n\t\t\t\tif !swapped {\n\t\t\t\t\tt.Error(\"Expected CompareAndSwap to succeed with UpdateIfChanged\")\n\t\t\t\t}\n\t\t\t\tif v, ok := m.Get(\"key1\"); !ok || v != 50 {\n\t\t\t\t\tt.Errorf(\"Expected value 50 for key 'key1', got %d\", v)\n\t\t\t\t}\n\t\t\t})\n\t\t\tt.Run(\"Does not swap if the value is the same\", func(t *testing.T) {\n\t\t\t\tm := New[string, int]()\n\t\t\t\tm.Set(\"key1\", 42)\n\t\t\t\tswapped := m.CompareAndSwap(\"key1\", UpdateIfChanged, 42)\n\t\t\t\tif swapped {\n\t\t\t\t\tt.Error(\"Expected CompareAndSwap to fail with UpdateIfChanged for same value\")\n\t\t\t\t}\n\t\t\t\tif v, ok := m.Get(\"key1\"); !ok || v != 42 {\n\t\t\t\t\tt.Errorf(\"Expected value 42 for key 'key1', got %d\", v)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "internal/syncset/set.go",
    "content": "package syncset\n\nimport \"sync\"\n\nfunc New[T comparable]() *Set[T] {\n\treturn &Set[T]{\n\t\tm:  make(map[T]struct{}),\n\t\tmu: sync.RWMutex{},\n\t}\n}\n\ntype Set[T comparable] struct {\n\tm  map[T]struct{}\n\tmu sync.RWMutex\n}\n\nfunc (s *Set[T]) Get(key T) (ok bool) {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\t_, ok = s.m[key]\n\treturn ok\n}\n\nfunc (s *Set[T]) Set(key T) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.m[key] = struct{}{}\n}\n\nfunc (s *Set[T]) Delete(key T) (deleted bool) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\t_, deleted = s.m[key]\n\tdelete(s.m, key)\n\treturn deleted\n}\n\nfunc (s *Set[T]) Count() int {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\treturn len(s.m)\n}\n"
  },
  {
    "path": "internal/syncset/set_test.go",
    "content": "package syncset\n\nimport \"testing\"\n\nfunc TestSet(t *testing.T) {\n\tt.Parallel()\n\tt.Run(\"Get\", func(t *testing.T) {\n\t\tt.Run(\"Returns false for non-existent items\", func(t *testing.T) {\n\t\t\ts := New[string]()\n\t\t\tif ok := s.Get(\"foo\"); ok {\n\t\t\t\tt.Error(\"expected Get to return false for non-existent item\")\n\t\t\t}\n\t\t})\n\t})\n\tt.Run(\"Set\", func(t *testing.T) {\n\t\ts := New[string]()\n\t\tt.Run(\"Can set new item\", func(t *testing.T) {\n\t\t\ts.Set(\"foo\")\n\t\t\tif !s.Get(\"foo\") {\n\t\t\t\tt.Error(\"expected Get to return true for item that was just set\")\n\t\t\t}\n\t\t})\n\t})\n\tt.Run(\"Delete\", func(t *testing.T) {\n\t\ts := New[string]()\n\t\tt.Run(\"Returns false for non-existent items\", func(t *testing.T) {\n\t\t\tif deleted := s.Delete(\"foo\"); deleted {\n\t\t\t\tt.Error(\"expected Delete to return false for non-existent item\")\n\t\t\t}\n\t\t})\n\t\tt.Run(\"Returns true for existing items\", func(t *testing.T) {\n\t\t\ts.Set(\"foo\")\n\t\t\tif deleted := s.Delete(\"foo\"); !deleted {\n\t\t\t\tt.Error(\"expected Delete to return true for existing item\")\n\t\t\t}\n\t\t\tif ok := s.Get(\"foo\"); ok {\n\t\t\t\tt.Error(\"expected Get to return false for item that was just deleted\")\n\t\t\t}\n\t\t})\n\t})\n\tt.Run(\"Count\", func(t *testing.T) {\n\t\tt.Run(\"Returns 0 for empty set\", func(t *testing.T) {\n\t\t\ts := New[string]()\n\t\t\tif count := s.Count(); count != 0 {\n\t\t\t\tt.Errorf(\"expected Count to return 0 for empty set, got %d\", count)\n\t\t\t}\n\t\t})\n\t\tt.Run(\"Returns correct count for non-empty set\", func(t *testing.T) {\n\t\t\ts := New[string]()\n\t\t\ts.Set(\"foo\")\n\t\t\ts.Set(\"bar\")\n\t\t\tif count := s.Count(); count != 2 {\n\t\t\t\tt.Errorf(\"expected Count to return 2 for set with two items, got %d\", count)\n\t\t\t}\n\t\t})\n\t\tt.Run(\"Returns correct count after deletions\", func(t *testing.T) {\n\t\t\ts := New[string]()\n\t\t\ts.Set(\"foo\")\n\t\t\ts.Set(\"bar\")\n\t\t\ts.Delete(\"foo\")\n\t\t\tif count := s.Count(); count != 1 {\n\t\t\t\tt.Errorf(\"expected Count to return 1 after deleting one item, got %d\", count)\n\t\t\t}\n\t\t})\n\t\tt.Run(\"Returns correct count after multiple deletions\", func(t *testing.T) {\n\t\t\ts := New[string]()\n\t\t\ts.Set(\"foo\")\n\t\t\ts.Set(\"bar\")\n\t\t\ts.Set(\"baz\")\n\t\t\ts.Delete(\"foo\")\n\t\t\ts.Delete(\"bar\")\n\t\t\tif count := s.Count(); count != 1 {\n\t\t\t\tt.Errorf(\"expected Count to return 1 after deleting two items, got %d\", count)\n\t\t\t}\n\t\t})\n\t})\n}\n"
  },
  {
    "path": "join.go",
    "content": "package templ\n\nimport (\n\t\"context\"\n\t\"io\"\n)\n\n// Join returns a single `templ.Component` that will render provided components in order.\n// If any of the components return an error the Join component will immediately return with the error.\nfunc Join(components ...Component) Component {\n\treturn ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\tfor _, c := range components {\n\t\t\tif err = c.Render(ctx, w); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n}\n"
  },
  {
    "path": "join_test.go",
    "content": "package templ_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestJoin(t *testing.T) {\n\tcompErr := errors.New(\"component error\")\n\n\thello := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\tif _, err := io.WriteString(w, \"Hello\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write string: %v\", err)\n\t\t}\n\t\treturn nil\n\t})\n\tworld := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\tif _, err := io.WriteString(w, \"World\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write string: %v\", err)\n\t\t}\n\t\treturn nil\n\t})\n\terr := templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\treturn compErr\n\t})\n\n\ttests := []struct {\n\t\tname           string\n\t\tinput          []templ.Component\n\t\texpectedOutput string\n\t\texpectedErr    error\n\t}{\n\t\t{\n\t\t\tname:           \"a nil slice of components produces no output\",\n\t\t\tinput:          nil,\n\t\t\texpectedOutput: \"\",\n\t\t},\n\t\t{\n\t\t\tname:           \"an empty list of components produces no output\",\n\t\t\tinput:          []templ.Component{},\n\t\t\texpectedOutput: \"\",\n\t\t},\n\t\t{\n\t\t\tname:           \"components are rendered in order\",\n\t\t\tinput:          []templ.Component{hello, world},\n\t\t\texpectedOutput: \"HelloWorld\",\n\t\t},\n\t\t{\n\t\t\tname:           \"components are rendered in order, and errors returned\",\n\t\t\tinput:          []templ.Component{hello, err},\n\t\t\texpectedOutput: \"Hello\",\n\t\t\texpectedErr:    compErr,\n\t\t},\n\t\t{\n\t\t\tname:           \"no further components are rendered after an error\",\n\t\t\tinput:          []templ.Component{err, hello},\n\t\t\texpectedOutput: \"\",\n\t\t\texpectedErr:    compErr,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot := templ.Join(tt.input...)\n\t\t\tb := new(bytes.Buffer)\n\t\t\terr := got.Render(context.Background(), b)\n\t\t\tif err != tt.expectedErr {\n\t\t\t\tt.Fatalf(\"failed to render component: %v\", err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expectedOutput, b.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "js.go",
    "content": "package templ\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"html\"\n)\n\n// JSUnsafeFuncCall calls arbitrary JavaScript in the js parameter.\n//\n// Use of this function presents a security risk - the JavaScript must come\n// from a trusted source, because it will be included as-is in the output.\nfunc JSUnsafeFuncCall[T ~string](js T) ComponentScript {\n\tsum := sha256.Sum256([]byte(js))\n\treturn ComponentScript{\n\t\tName: \"jsUnsafeFuncCall_\" + hex.EncodeToString(sum[:]),\n\t\t// Function is empty because the body of the function is defined elsewhere,\n\t\t// e.g. in a <script> tag within a templ.Once block.\n\t\tFunction:   \"\",\n\t\tCall:       html.EscapeString(string(js)),\n\t\tCallInline: string(js),\n\t}\n}\n\n// JSFuncCall calls a JavaScript function with the given arguments.\n//\n// It can be used in event handlers, e.g. onclick, onhover, etc. or\n// directly in HTML.\nfunc JSFuncCall[T ~string](functionName T, args ...any) ComponentScript {\n\tcall := SafeScript(string(functionName), args...)\n\tsum := sha256.Sum256([]byte(call))\n\treturn ComponentScript{\n\t\tName: \"jsFuncCall_\" + hex.EncodeToString(sum[:]),\n\t\t// Function is empty because the body of the function is defined elsewhere,\n\t\t// e.g. in a <script> tag within a templ.Once block.\n\t\tFunction:   \"\",\n\t\tCall:       call,\n\t\tCallInline: SafeScriptInline(string(functionName), args...),\n\t}\n}\n"
  },
  {
    "path": "js_test.go",
    "content": "package templ\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\n// Note: use of the RawEventHandler and JSFuncCall in ExpressionAttributes is tested in the parser package.\n\nfunc TestJSUnsafeFuncCall(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tjs       string\n\t\texpected ComponentScript\n\t}{\n\t\t{\n\t\t\tname: \"alert\",\n\t\t\tjs:   \"alert('hello')\",\n\t\t\texpected: ComponentScript{\n\t\t\t\tName:     \"jsUnsafeFuncCall_bc8b29d9abedc43cb4d79ec0af23be8c4255a4b76691aecf23ba3b0b8ab90011\",\n\t\t\t\tFunction: \"\",\n\t\t\t\t// Note that the Call field is attribute encoded.\n\t\t\t\tCall: \"alert(&#39;hello&#39;)\",\n\t\t\t\t// Whereas the CallInline field is what you would see inside a <script> tag.\n\t\t\t\tCallInline: \"alert('hello')\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"immediately executed function\",\n\t\t\tjs:   \"(function(x) { x < 3 ? alert('hello less than 3') : alert('more than 3'); })(2);\",\n\t\t\texpected: ComponentScript{\n\t\t\t\tName:       \"jsUnsafeFuncCall_e4c24908f83227fd10c1a984fe8f99e15bfb3f195985af517253f6a72ec9106b\",\n\t\t\t\tFunction:   \"\",\n\t\t\t\tCall:       \"(function(x) { x &lt; 3 ? alert(&#39;hello less than 3&#39;) : alert(&#39;more than 3&#39;); })(2);\",\n\t\t\t\tCallInline: \"(function(x) { x < 3 ? alert('hello less than 3') : alert('more than 3'); })(2);\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tactual := JSUnsafeFuncCall(tt.js)\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestJSFuncCall(t *testing.T) {\n\ttests := []struct {\n\t\tname                    string\n\t\tfunctionName            string\n\t\targs                    []any\n\t\texpected                ComponentScript\n\t\texpectedComponentOutput string\n\t}{\n\t\t{\n\t\t\tname:         \"no arguments are supported\",\n\t\t\tfunctionName: \"doSomething\",\n\t\t\targs:         nil,\n\t\t\texpected: ComponentScript{\n\t\t\t\tName:       \"jsFuncCall_6e742483001f8d3c67652945c597b5a2025a7411cb9d1bae2f9e160bebfeb4c6\",\n\t\t\t\tFunction:   \"\",\n\t\t\t\tCall:       \"doSomething()\",\n\t\t\t\tCallInline: \"doSomething()\",\n\t\t\t},\n\t\t\texpectedComponentOutput: `<script>doSomething()</script>`,\n\t\t},\n\t\t{\n\t\t\tname:         \"single argument is supported\",\n\t\t\tfunctionName: \"alert\",\n\t\t\targs:         []any{\"hello\"},\n\t\t\texpected: ComponentScript{\n\t\t\t\tName:       \"jsFuncCall_92df7244f17dc5bfc41dfd02043df695e4664f8bf42c265a46d79b32b97693d0\",\n\t\t\t\tFunction:   \"\",\n\t\t\t\tCall:       \"alert(&#34;hello&#34;)\",\n\t\t\t\tCallInline: `alert(\"hello\")`,\n\t\t\t},\n\t\t\texpectedComponentOutput: `<script>alert(\"hello\")</script>`,\n\t\t},\n\t\t{\n\t\t\tname:         \"multiple arguments are supported\",\n\t\t\tfunctionName: \"console.log\",\n\t\t\targs:         []any{\"hello\", \"world\"},\n\t\t\texpected: ComponentScript{\n\t\t\t\tName:       \"jsFuncCall_2b3416c14fc2700d01e0013e7b7076bb8dd5f3126d19e2e801de409163e3960c\",\n\t\t\t\tFunction:   \"\",\n\t\t\t\tCall:       \"console.log(&#34;hello&#34;,&#34;world&#34;)\",\n\t\t\t\tCallInline: `console.log(\"hello\",\"world\")`,\n\t\t\t},\n\t\t\texpectedComponentOutput: `<script>console.log(\"hello\",\"world\")</script>`,\n\t\t},\n\t\t{\n\t\t\tname:         \"attribute injection fails\",\n\t\t\tfunctionName: `\" onmouseover=\"alert('hello')`,\n\t\t\targs:         nil,\n\t\t\texpected: ComponentScript{\n\t\t\t\tName:       \"jsFuncCall_e56d1214f3b4fbf27406f209e3f4a58c2842fa2760b6d83da5ee72e04c89f913\",\n\t\t\t\tFunction:   \"\",\n\t\t\t\tCall:       \"__templ_invalid_js_function_name()\",\n\t\t\t\tCallInline: \"__templ_invalid_js_function_name()\",\n\t\t\t},\n\t\t\texpectedComponentOutput: `<script>__templ_invalid_js_function_name()</script>`,\n\t\t},\n\t\t{\n\t\t\tname:         \"closing the script and injecting HTML fails\",\n\t\t\tfunctionName: `</script><div>Hello</div><script>`,\n\t\t\targs:         nil,\n\t\t\texpected: ComponentScript{\n\t\t\t\tName:       \"jsFuncCall_e56d1214f3b4fbf27406f209e3f4a58c2842fa2760b6d83da5ee72e04c89f913\",\n\t\t\t\tFunction:   \"\",\n\t\t\t\tCall:       \"__templ_invalid_js_function_name()\",\n\t\t\t\tCallInline: \"__templ_invalid_js_function_name()\",\n\t\t\t},\n\t\t\texpectedComponentOutput: `<script>__templ_invalid_js_function_name()</script>`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Test creation.\n\t\t\tactual := JSFuncCall(tt.functionName, tt.args...)\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\n\t\t\t// Test rendering.\n\t\t\tbuf := new(bytes.Buffer)\n\t\t\terr := actual.Render(context.Background(), buf)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expectedComponentOutput, buf.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\n\t\t})\n\t}\n}\n\nfunc TestJSFunctionNameRegexp(t *testing.T) {\n\ttests := []struct {\n\t\tinput    string\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tinput:    \"console.log\",\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tinput:    \"alert\",\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tinput:    \"console.log('hello')\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tinput:    \"</script><div>Hello</div><script>\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tinput:    `\" onmouseover=\"alert('hello')`,\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tinput:    \"(new Date()).getTime\",\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tinput:    \"expressionThatReturnsAFunction()\",\n\t\t\texpected: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.input, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tactual := jsFunctionName.MatchString(tt.input)\n\t\t\tif actual != tt.expected {\n\t\t\t\tt.Errorf(\"expected %v, got %v\", tt.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "jsonscript.go",
    "content": "package templ\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n)\n\nvar _ Component = JSONScriptElement{}\n\n// JSONScript renders a JSON object inside a script element.\n// e.g. <script type=\"application/json\">{\"foo\":\"bar\"}</script>\nfunc JSONScript(id string, data any) JSONScriptElement {\n\treturn JSONScriptElement{\n\t\tID:    id,\n\t\tType:  \"application/json\",\n\t\tData:  data,\n\t\tNonce: GetNonce,\n\t}\n}\n\n// WithType sets the value of the type attribute of the script element.\nfunc (j JSONScriptElement) WithType(t string) JSONScriptElement {\n\tj.Type = t\n\treturn j\n}\n\n// WithNonceFromString sets the value of the nonce attribute of the script element to the given string.\nfunc (j JSONScriptElement) WithNonceFromString(nonce string) JSONScriptElement {\n\tj.Nonce = func(context.Context) string {\n\t\treturn nonce\n\t}\n\treturn j\n}\n\n// WithNonceFrom sets the value of the nonce attribute of the script element to the value returned by the given function.\nfunc (j JSONScriptElement) WithNonceFrom(f func(context.Context) string) JSONScriptElement {\n\tj.Nonce = f\n\treturn j\n}\n\ntype JSONScriptElement struct {\n\t// ID of the element in the DOM.\n\tID string\n\t// Type of the script element, defaults to \"application/json\".\n\tType string\n\t// Data that will be encoded as JSON.\n\tData any\n\t// Nonce is a function that returns a CSP nonce.\n\t// Defaults to CSPNonceFromContext.\n\t// See https://content-security-policy.com/nonce for more information.\n\tNonce func(ctx context.Context) string\n}\n\nfunc (j JSONScriptElement) Render(ctx context.Context, w io.Writer) (err error) {\n\tif _, err = io.WriteString(w, \"<script\"); err != nil {\n\t\treturn err\n\t}\n\tif j.ID != \"\" {\n\t\tif _, err = fmt.Fprintf(w, \" id=\\\"%s\\\"\", EscapeString(j.ID)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif j.Type != \"\" {\n\t\tif _, err = fmt.Fprintf(w, \" type=\\\"%s\\\"\", EscapeString(j.Type)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif nonce := j.Nonce(ctx); nonce != \"\" {\n\t\tif _, err = fmt.Fprintf(w, \" nonce=\\\"%s\\\"\", EscapeString(nonce)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif _, err = io.WriteString(w, \">\"); err != nil {\n\t\treturn err\n\t}\n\tif err = json.NewEncoder(w).Encode(j.Data); err != nil {\n\t\treturn err\n\t}\n\tif _, err = io.WriteString(w, \"</script>\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "jsonscript_test.go",
    "content": "package templ_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestJSONScriptElement(t *testing.T) {\n\tdata := map[string]any{\"foo\": \"bar\"}\n\ttests := []struct {\n\t\tname     string\n\t\tctx      context.Context\n\t\te        templ.JSONScriptElement\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"renders data as JSON inside a script element\",\n\t\t\te:        templ.JSONScript(\"id\", data),\n\t\t\texpected: \"<script id=\\\"id\\\" type=\\\"application/json\\\">{\\\"foo\\\":\\\"bar\\\"}\\n</script>\",\n\t\t},\n\t\t{\n\t\t\tname:     \"if a nonce is available in the context, it is used\",\n\t\t\tctx:      templ.WithNonce(context.Background(), \"nonce-from-context\"),\n\t\t\te:        templ.JSONScript(\"idc\", data),\n\t\t\texpected: \"<script id=\\\"idc\\\" type=\\\"application/json\\\" nonce=\\\"nonce-from-context\\\">{\\\"foo\\\":\\\"bar\\\"}\\n</script>\",\n\t\t},\n\t\t{\n\t\t\tname:     \"if a nonce is provided, it is used\",\n\t\t\te:        templ.JSONScript(\"ids\", data).WithNonceFromString(\"nonce-from-string\"),\n\t\t\texpected: \"<script id=\\\"ids\\\" type=\\\"application/json\\\" nonce=\\\"nonce-from-string\\\">{\\\"foo\\\":\\\"bar\\\"}\\n</script>\",\n\t\t},\n\t\t{\n\t\t\tname:     \"if a nonce function is provided, it is used\",\n\t\t\te:        templ.JSONScript(\"idf\", data).WithNonceFrom(func(context.Context) string { return \"nonce-from-function\" }),\n\t\t\texpected: \"<script id=\\\"idf\\\" type=\\\"application/json\\\" nonce=\\\"nonce-from-function\\\">{\\\"foo\\\":\\\"bar\\\"}\\n</script>\",\n\t\t},\n\t\t{\n\t\t\tname:     \"if a type is provided, it is used\",\n\t\t\te:        templ.JSONScript(\"idt\", data).WithType(\"application/ld+json\"),\n\t\t\texpected: \"<script id=\\\"idt\\\" type=\\\"application/ld+json\\\">{\\\"foo\\\":\\\"bar\\\"}\\n</script>\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tw := new(bytes.Buffer)\n\t\t\tif err := tt.e.Render(tt.ctx, w); err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, w.String()); diff != \"\" {\n\t\t\t\tt.Fatalf(\"unexpected output (-want +got):\\n%s\", diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "jsonstring.go",
    "content": "package templ\n\nimport (\n\t\"encoding/json\"\n)\n\n// JSONString returns a JSON encoded string of v.\nfunc JSONString(v any) (string, error) {\n\tb, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(b), nil\n}\n"
  },
  {
    "path": "jsonstring_test.go",
    "content": "package templ_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n)\n\nfunc TestJSONString(t *testing.T) {\n\tt.Run(\"renders input data as a JSON string\", func(t *testing.T) {\n\t\tdata := map[string]any{\"foo\": \"bar\"}\n\t\tactual, err := templ.JSONString(data)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\texpected := \"{\\\"foo\\\":\\\"bar\\\"}\"\n\t\tif actual != expected {\n\t\t\tt.Fatalf(\"unexpected output: want %q, got %q\", expected, actual)\n\t\t}\n\t})\n\tt.Run(\"returns an error if the data cannot be marshalled\", func(t *testing.T) {\n\t\tdata := make(chan int)\n\t\t_, err := templ.JSONString(data)\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"expected an error, got nil\")\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2019, The Go Language Server Authors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* 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\n* 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": "lsp/README.md",
    "content": "# lsp\n\nForked from https://github.com/go-language-server repos.\n"
  },
  {
    "path": "lsp/jsonrpc2/codes.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\n// Code is an error code as defined in the JSON-RPC spec.\ntype Code int32\n\n// list of JSON-RPC error codes.\nconst (\n\t// ParseError is the invalid JSON was received by the server.\n\t// An error occurred on the server while parsing the JSON text.\n\tParseError Code = -32700\n\n\t// InvalidRequest is the JSON sent is not a valid Request object.\n\tInvalidRequest Code = -32600\n\n\t// MethodNotFound is the method does not exist / is not available.\n\tMethodNotFound Code = -32601\n\n\t// InvalidParams is the invalid method parameter(s).\n\tInvalidParams Code = -32602\n\n\t// InternalError is the internal JSON-RPC error.\n\tInternalError Code = -32603\n\n\t// JSONRPCReservedErrorRangeStart is the start range of JSON RPC reserved error codes.\n\t//\n\t// It doesn't denote a real error code. No LSP error codes should\n\t// be defined between the start and end range. For backwards\n\t// compatibility the \"ServerNotInitialized\" and the \"UnknownErrorCode\"\n\t// are left in the range.\n\t//\n\t// @since 3.16.0.\n\tJSONRPCReservedErrorRangeStart Code = -32099\n\n\t// CodeServerErrorStart reserved for implementation-defined server-errors.\n\t//\n\t// Deprecated: Use JSONRPCReservedErrorRangeStart instead.\n\tCodeServerErrorStart = JSONRPCReservedErrorRangeStart\n\n\t// ServerNotInitialized is the error of server not initialized.\n\tServerNotInitialized Code = -32002\n\n\t// UnknownError should be used for all non coded errors.\n\tUnknownError Code = -32001\n\n\t// JSONRPCReservedErrorRangeEnd is the start range of JSON RPC reserved error codes.\n\t//\n\t// It doesn't denote a real error code.\n\t//\n\t// @since 3.16.0.\n\tJSONRPCReservedErrorRangeEnd Code = -32000\n\n\t// CodeServerErrorEnd reserved for implementation-defined server-errors.\n\t//\n\t// Deprecated: Use JSONRPCReservedErrorRangeEnd instead.\n\tCodeServerErrorEnd = JSONRPCReservedErrorRangeEnd\n)\n\n// This file contains the Go forms of the wire specification.\n//\n// See http://www.jsonrpc.org/specification for details.\n//\n// list of JSON-RPC errors.\nvar (\n\t// ErrUnknown should be used for all non coded errors.\n\tErrUnknown = NewError(UnknownError, \"JSON-RPC unknown error\")\n\n\t// ErrParse is used when invalid JSON was received by the server.\n\tErrParse = NewError(ParseError, \"JSON-RPC parse error\")\n\n\t// ErrInvalidRequest is used when the JSON sent is not a valid Request object.\n\tErrInvalidRequest = NewError(InvalidRequest, \"JSON-RPC invalid request\")\n\n\t// ErrMethodNotFound should be returned by the handler when the method does\n\t// not exist / is not available.\n\tErrMethodNotFound = NewError(MethodNotFound, \"JSON-RPC method not found\")\n\n\t// ErrInvalidParams should be returned by the handler when method\n\t// parameter(s) were invalid.\n\tErrInvalidParams = NewError(InvalidParams, \"JSON-RPC invalid params\")\n\n\t// ErrInternal is not currently returned but defined for completeness.\n\tErrInternal = NewError(InternalError, \"JSON-RPC internal error\")\n)\n"
  },
  {
    "path": "lsp/jsonrpc2/conn.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"encoding/json\"\n)\n\n// Conn is the common interface to jsonrpc clients and servers.\n//\n// Conn is bidirectional; it does not have a designated server or client end.\n// It manages the jsonrpc2 protocol, connecting responses back to their calls.\ntype Conn interface {\n\t// Call invokes the target method and waits for a response.\n\t//\n\t// The params will be marshaled to JSON before sending over the wire, and will\n\t// be handed to the method invoked.\n\t//\n\t// The response will be unmarshaled from JSON into the result.\n\t//\n\t// The id returned will be unique from this connection, and can be used for\n\t// logging or tracking.\n\tCall(ctx context.Context, method string, params, result any) (ID, error)\n\n\t// Notify invokes the target method but does not wait for a response.\n\t//\n\t// The params will be marshaled to JSON before sending over the wire, and will\n\t// be handed to the method invoked.\n\tNotify(ctx context.Context, method string, params any) error\n\n\t// Go starts a goroutine to handle the connection.\n\t//\n\t// It must be called exactly once for each Conn. It returns immediately.\n\t// Must block on Done() to wait for the connection to shut down.\n\t//\n\t// This is a temporary measure, this should be started automatically in the\n\t// future.\n\tGo(ctx context.Context, handler Handler)\n\n\t// Close closes the connection and it's underlying stream.\n\t//\n\t// It does not wait for the close to complete, use the Done() channel for\n\t// that.\n\tClose() error\n\n\t// Done returns a channel that will be closed when the processing goroutine\n\t// has terminated, which will happen if Close() is called or an underlying\n\t// stream is closed.\n\tDone() <-chan struct{}\n\n\t// Err returns an error if there was one from within the processing goroutine.\n\t//\n\t// If err returns non nil, the connection will be already closed or closing.\n\tErr() error\n}\n\ntype conn struct {\n\tseq       int32                 // access atomically\n\twriteMu   sync.Mutex            // protects writes to the stream\n\tstream    Stream                // supplied stream\n\tpendingMu sync.Mutex            // protects the pending map\n\tpending   map[ID]chan *Response // holds the pending response channel with the ID as the key.\n\n\tdone chan struct{} // closed when done\n\terr  atomic.Value  // holds run error\n}\n\n// NewConn creates a new connection object around the supplied stream.\nfunc NewConn(s Stream) Conn {\n\tconn := &conn{\n\t\tstream:  s,\n\t\tpending: make(map[ID]chan *Response),\n\t\tdone:    make(chan struct{}),\n\t}\n\treturn conn\n}\n\n// Call implements Conn.\nfunc (c *conn) Call(ctx context.Context, method string, params, result any) (id ID, err error) {\n\t// generate a new request identifier\n\tid = NewNumberID(atomic.AddInt32(&c.seq, 1))\n\tcall, err := NewCall(id, method, params)\n\tif err != nil {\n\t\treturn id, fmt.Errorf(\"marshaling call parameters: %w\", err)\n\t}\n\n\t// We have to add ourselves to the pending map before we send, otherwise we\n\t// are racing the response. Also add a buffer to rchan, so that if we get a\n\t// wire response between the time this call is cancelled and id is deleted\n\t// from c.pending, the send to rchan will not block.\n\trchan := make(chan *Response, 1)\n\n\tc.pendingMu.Lock()\n\tc.pending[id] = rchan\n\tc.pendingMu.Unlock()\n\n\tdefer func() {\n\t\tc.pendingMu.Lock()\n\t\tdelete(c.pending, id)\n\t\tc.pendingMu.Unlock()\n\t}()\n\n\t// now we are ready to send\n\t_, err = c.write(ctx, call)\n\tif err != nil {\n\t\t// sending failed, we will never get a response, so don't leave it pending\n\t\treturn id, err\n\t}\n\n\t// now wait for the response\n\tselect {\n\tcase resp := <-rchan:\n\t\t// is it an error response?\n\t\tif resp.err != nil {\n\t\t\treturn id, resp.err\n\t\t}\n\n\t\tif result == nil || len(resp.result) == 0 {\n\t\t\treturn id, nil\n\t\t}\n\n\t\tdec := json.NewDecoder(bytes.NewReader(resp.result))\n\t\tif err := dec.Decode(result); err != nil {\n\t\t\treturn id, fmt.Errorf(\"unmarshaling result: %w\", err)\n\t\t}\n\n\t\treturn id, nil\n\n\tcase <-ctx.Done():\n\t\treturn id, ctx.Err()\n\t}\n}\n\n// Notify implements Conn.\nfunc (c *conn) Notify(ctx context.Context, method string, params any) (err error) {\n\tnotify, err := NewNotification(method, params)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshaling notify parameters: %w\", err)\n\t}\n\n\t_, err = c.write(ctx, notify)\n\n\treturn err\n}\n\nfunc (c *conn) replier(req Message) Replier {\n\treturn func(ctx context.Context, result any, err error) error {\n\t\tcall, ok := req.(*Call)\n\t\tif !ok {\n\t\t\t// request was a notify, no need to respond\n\t\t\treturn nil\n\t\t}\n\n\t\tresponse, err := NewResponse(call.id, result, err)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t_, err = c.write(ctx, response)\n\t\tif err != nil {\n\t\t\t// TODO(iancottrell): if a stream write fails, we really need to shut down the whole stream\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (c *conn) write(ctx context.Context, msg Message) (int64, error) {\n\tc.writeMu.Lock()\n\tn, err := c.stream.Write(ctx, msg)\n\tc.writeMu.Unlock()\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"write to stream: %w\", err)\n\t}\n\n\treturn n, nil\n}\n\n// Go implements Conn.\nfunc (c *conn) Go(ctx context.Context, handler Handler) {\n\tgo c.run(ctx, handler)\n}\n\nfunc (c *conn) run(ctx context.Context, handler Handler) {\n\tdefer close(c.done)\n\n\tfor {\n\t\t// get the next message\n\t\tmsg, _, err := c.stream.Read(ctx)\n\t\tif err != nil {\n\t\t\t// The stream failed, we cannot continue.\n\t\t\tc.fail(err)\n\t\t\treturn\n\t\t}\n\n\t\tswitch msg := msg.(type) {\n\t\tcase Request:\n\t\t\tif err := handler(ctx, c.replier(msg), msg); err != nil {\n\t\t\t\tc.fail(err)\n\t\t\t}\n\n\t\tcase *Response:\n\t\t\t// If method is not set, this should be a response, in which case we must\n\t\t\t// have an id to send the response back to the caller.\n\t\t\tc.pendingMu.Lock()\n\t\t\trchan, ok := c.pending[msg.id]\n\t\t\tc.pendingMu.Unlock()\n\t\t\tif ok {\n\t\t\t\trchan <- msg\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Close implements Conn.\nfunc (c *conn) Close() error {\n\treturn c.stream.Close()\n}\n\n// Done implements Conn.\nfunc (c *conn) Done() <-chan struct{} {\n\treturn c.done\n}\n\n// Err implements Conn.\nfunc (c *conn) Err() error {\n\tif err := c.err.Load(); err != nil {\n\t\treturn err.(error)\n\t}\n\treturn nil\n}\n\n// fail sets a failure condition on the stream and closes it.\nfunc (c *conn) fail(err error) {\n\tc.err.Store(err)\n\t_ = c.stream.Close()\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/errors.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"encoding/json\"\n)\n\n// Error represents a JSON-RPC error.\ntype Error struct {\n\t// Code a number indicating the error type that occurred.\n\tCode Code `json:\"code\"`\n\n\t// Message a string providing a short description of the error.\n\tMessage string `json:\"message\"`\n\n\t// Data a Primitive or Structured value that contains additional\n\t// information about the error. Can be omitted.\n\tData *json.RawMessage `json:\"data,omitempty\"`\n}\n\n// compile time check whether the Error implements error interface.\nvar _ error = (*Error)(nil)\n\n// Error implements error.Error.\nfunc (e *Error) Error() string {\n\tif e == nil {\n\t\treturn \"\"\n\t}\n\treturn e.Message\n}\n\n// Unwrap implements errors.Unwrap.\n//\n// Returns the error underlying the receiver, which may be nil.\nfunc (e *Error) Unwrap() error { return errors.New(e.Message) }\n\n// NewError builds a Error struct for the suppied code and message.\nfunc NewError(c Code, message string) *Error {\n\treturn &Error{\n\t\tCode:    c,\n\t\tMessage: message,\n\t}\n}\n\n// Errorf builds a Error struct for the suppied code, format and args.\nfunc Errorf(c Code, format string, args ...any) *Error {\n\treturn &Error{\n\t\tCode:    c,\n\t\tMessage: fmt.Sprintf(format, args...),\n\t}\n}\n\n// constErr represents a error constant.\ntype constErr string\n\n// compile time check whether the constErr implements error interface.\nvar _ error = (*constErr)(nil)\n\n// Error implements error.Error.\nfunc (e constErr) Error() string { return string(e) }\n\nconst (\n\t// ErrIdleTimeout is returned when serving timed out waiting for new connections.\n\tErrIdleTimeout = constErr(\"timed out waiting for new connections\")\n)\n"
  },
  {
    "path": "lsp/jsonrpc2/handler.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n)\n\n// Handler is invoked to handle incoming requests.\n//\n// The Replier sends a reply to the request and must be called exactly once.\ntype Handler func(ctx context.Context, reply Replier, req Request) error\n\n// Replier is passed to handlers to allow them to reply to the request.\n//\n// If err is set then result will be ignored.\ntype Replier func(ctx context.Context, result any, err error) error\n\n// MethodNotFoundHandler is a Handler that replies to all call requests with the\n// standard method not found response.\n//\n// This should normally be the final handler in a chain.\nfunc MethodNotFoundHandler(ctx context.Context, reply Replier, req Request) error {\n\treturn reply(ctx, nil, fmt.Errorf(\"%q: %w\", req.Method(), ErrMethodNotFound))\n}\n\n// ReplyHandler creates a Handler that panics if the wrapped handler does\n// not call Reply for every request that it is passed.\nfunc ReplyHandler(handler Handler) (h Handler) {\n\th = Handler(func(ctx context.Context, reply Replier, req Request) error {\n\t\tcalled := false\n\t\terr := handler(ctx, func(ctx context.Context, result any, err error) error {\n\t\t\tif called {\n\t\t\t\tpanic(fmt.Errorf(\"request %q replied to more than once\", req.Method()))\n\t\t\t}\n\t\t\tcalled = true\n\n\t\t\treturn reply(ctx, result, err)\n\t\t}, req)\n\t\tif !called {\n\t\t\tpanic(fmt.Errorf(\"request %q was never replied to\", req.Method()))\n\t\t}\n\t\treturn err\n\t})\n\n\treturn h\n}\n\n// CancelHandler returns a handler that supports cancellation, and a function\n// that can be used to trigger canceling in progress requests.\nfunc CancelHandler(handler Handler) (h Handler, canceller func(id ID)) {\n\tvar mu sync.Mutex\n\thandling := make(map[ID]context.CancelFunc)\n\n\th = Handler(func(ctx context.Context, reply Replier, req Request) error {\n\t\tif call, ok := req.(*Call); ok {\n\t\t\tcancelCtx, cancel := context.WithCancel(ctx)\n\t\t\tctx = cancelCtx\n\n\t\t\tmu.Lock()\n\t\t\thandling[call.ID()] = cancel\n\t\t\tmu.Unlock()\n\n\t\t\tinnerReply := reply\n\t\t\treply = func(ctx context.Context, result any, err error) error {\n\t\t\t\tmu.Lock()\n\t\t\t\tdelete(handling, call.ID())\n\t\t\t\tmu.Unlock()\n\t\t\t\treturn innerReply(ctx, result, err)\n\t\t\t}\n\t\t}\n\t\treturn handler(ctx, reply, req)\n\t})\n\n\tcanceller = func(id ID) {\n\t\tmu.Lock()\n\t\tcancel, found := handling[id]\n\t\tmu.Unlock()\n\t\tif found {\n\t\t\tcancel()\n\t\t}\n\t}\n\n\treturn h, canceller\n}\n\n// AsyncHandler returns a handler that processes each request goes in its own\n// goroutine.\n//\n// The handler returns immediately, without the request being processed.\n// Each request then waits for the previous request to finish before it starts.\n//\n// This allows the stream to unblock at the cost of unbounded goroutines\n// all stalled on the previous one.\nfunc AsyncHandler(handler Handler) (h Handler) {\n\tnextRequest := make(chan struct{})\n\tclose(nextRequest)\n\n\th = Handler(func(ctx context.Context, reply Replier, req Request) error {\n\t\twaitForPrevious := nextRequest\n\t\tnextRequest = make(chan struct{})\n\t\tunlockNext := nextRequest\n\t\tinnerReply := reply\n\t\treply = func(ctx context.Context, result any, err error) error {\n\t\t\tclose(unlockNext)\n\t\t\treturn innerReply(ctx, result, err)\n\t\t}\n\n\t\tgo func() {\n\t\t\t<-waitForPrevious\n\t\t\t_ = handler(ctx, reply, req)\n\t\t}()\n\t\treturn nil\n\t})\n\n\treturn h\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/jsonrpc2.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\n// Package jsonrpc2 is an implementation of the JSON-RPC 2 specification for Go.\n//\n// https://www.jsonrpc.org/specification\npackage jsonrpc2 // import \"github.com/a-h/templ/lsp/jsonrpc2\"\n"
  },
  {
    "path": "lsp/jsonrpc2/jsonrpc2_test.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"path\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n)\n\nconst (\n\tmethodNoArgs    = \"no_args\"\n\tmethodOneString = \"one_string\"\n\tmethodOneNumber = \"one_number\"\n\tmethodJoin      = \"join\"\n)\n\ntype callTest struct {\n\tmethod string\n\tparams any\n\texpect any\n}\n\nvar callTests = []callTest{\n\t{\n\t\tmethod: methodNoArgs,\n\t\tparams: nil,\n\t\texpect: true,\n\t},\n\t{\n\t\tmethod: methodOneString,\n\t\tparams: \"fish\",\n\t\texpect: \"got:fish\",\n\t},\n\t{\n\t\tmethod: methodOneNumber,\n\t\tparams: 10,\n\t\texpect: \"got:10\",\n\t},\n\t{\n\t\tmethod: methodJoin,\n\t\tparams: []string{\"a\", \"b\", \"c\"},\n\t\texpect: \"a/b/c\",\n\t},\n\t// TODO: expand the test cases\n}\n\nfunc (test *callTest) newResults() any {\n\tswitch e := test.expect.(type) {\n\tcase []any:\n\t\tvar r []any\n\t\tfor _, v := range e {\n\t\t\tr = append(r, reflect.New(reflect.TypeOf(v)).Interface())\n\t\t}\n\t\treturn r\n\n\tcase nil:\n\t\treturn nil\n\n\tdefault:\n\t\treturn reflect.New(reflect.TypeOf(test.expect)).Interface()\n\t}\n}\n\nfunc (test *callTest) verifyResults(t *testing.T, results any) {\n\tt.Helper()\n\n\tif results == nil {\n\t\treturn\n\t}\n\n\tval := reflect.Indirect(reflect.ValueOf(results)).Interface()\n\tif !reflect.DeepEqual(val, test.expect) {\n\t\tt.Errorf(\"%v:Results are incorrect, got %+v expect %+v\", test.method, val, test.expect)\n\t}\n}\n\nfunc TestRequest(t *testing.T) {\n\tctx := context.Background()\n\ta, b, done := prepare(ctx, t)\n\tdefer done()\n\n\tfor _, test := range callTests {\n\t\tt.Run(test.method, func(t *testing.T) {\n\t\t\tresults := test.newResults()\n\t\t\tif _, err := a.Call(ctx, test.method, test.params, results); err != nil {\n\t\t\t\tt.Fatalf(\"%v:Call failed: %v\", test.method, err)\n\t\t\t}\n\t\t\ttest.verifyResults(t, results)\n\n\t\t\tif _, err := b.Call(ctx, test.method, test.params, results); err != nil {\n\t\t\t\tt.Fatalf(\"%v:Call failed: %v\", test.method, err)\n\t\t\t}\n\t\t\ttest.verifyResults(t, results)\n\t\t})\n\t}\n}\n\nfunc prepare(ctx context.Context, t *testing.T) (a, b jsonrpc2.Conn, done func()) {\n\tt.Helper()\n\n\t// make a wait group that can be used to wait for the system to shut down\n\taPipe, bPipe := net.Pipe()\n\ta = run(ctx, aPipe)\n\tb = run(ctx, bPipe)\n\tdone = func() {\n\t\t_ = a.Close()\n\t\t_ = b.Close()\n\t\t<-a.Done()\n\t\t<-b.Done()\n\t}\n\n\treturn a, b, done\n}\n\nfunc run(ctx context.Context, nc io.ReadWriteCloser) jsonrpc2.Conn {\n\tstream := jsonrpc2.NewStream(nc)\n\tconn := jsonrpc2.NewConn(stream)\n\tconn.Go(ctx, testHandler())\n\n\treturn conn\n}\n\nfunc testHandler() jsonrpc2.Handler {\n\treturn func(ctx context.Context, reply jsonrpc2.Replier, req jsonrpc2.Request) error {\n\t\tswitch req.Method() {\n\t\tcase methodNoArgs:\n\t\t\tif len(req.Params()) > 0 {\n\t\t\t\treturn reply(ctx, nil, fmt.Errorf(\"expected no params: %w\", jsonrpc2.ErrInvalidParams))\n\t\t\t}\n\t\t\treturn reply(ctx, true, nil)\n\n\t\tcase methodOneString:\n\t\t\tvar v string\n\t\t\tdec := json.NewDecoder(bytes.NewReader(req.Params()))\n\t\t\tif err := dec.Decode(&v); err != nil {\n\t\t\t\treturn reply(ctx, nil, fmt.Errorf(\"%s: %w\", jsonrpc2.ErrParse, err))\n\t\t\t}\n\t\t\treturn reply(ctx, \"got:\"+v, nil)\n\n\t\tcase methodOneNumber:\n\t\t\tvar v int\n\t\t\tdec := json.NewDecoder(bytes.NewReader(req.Params()))\n\t\t\tif err := dec.Decode(&v); err != nil {\n\t\t\t\treturn reply(ctx, nil, fmt.Errorf(\"%s: %w\", jsonrpc2.ErrParse, err))\n\t\t\t}\n\t\t\treturn reply(ctx, fmt.Sprintf(\"got:%d\", v), nil)\n\n\t\tcase methodJoin:\n\t\t\tvar v []string\n\t\t\tdec := json.NewDecoder(bytes.NewReader(req.Params()))\n\t\t\tif err := dec.Decode(&v); err != nil {\n\t\t\t\treturn reply(ctx, nil, fmt.Errorf(\"%s: %w\", jsonrpc2.ErrParse, err))\n\t\t\t}\n\t\t\treturn reply(ctx, path.Join(v...), nil)\n\n\t\tdefault:\n\t\t\treturn jsonrpc2.MethodNotFoundHandler(ctx, reply, req)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/message.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"encoding/json\"\n)\n\n// Message is the interface to all JSON-RPC message types.\n//\n// They share no common functionality, but are a closed set of concrete types\n// that are allowed to implement this interface.\n//\n// The message types are *Call, *Response and *Notification.\ntype Message interface {\n\t// jsonrpc2Message is used to make the set of message implementations a\n\t// closed set.\n\tjsonrpc2Message()\n}\n\n// Request is the shared interface to jsonrpc2 messages that request\n// a method be invoked.\n//\n// The request types are a closed set of *Call and *Notification.\ntype Request interface {\n\tMessage\n\n\t// Method is a string containing the method name to invoke.\n\tMethod() string\n\t// Params is either a struct or an array with the parameters of the method.\n\tParams() json.RawMessage\n\n\t// jsonrpc2Request is used to make the set of request implementations closed.\n\tjsonrpc2Request()\n}\n\n// Call is a request that expects a response.\n//\n// The response will have a matching ID.\ntype Call struct {\n\t// Method is a string containing the method name to invoke.\n\tmethod string\n\t// Params is either a struct or an array with the parameters of the method.\n\tparams json.RawMessage\n\t// id of this request, used to tie the Response back to the request.\n\tid ID\n}\n\n// make sure a Call implements the Request, json.Marshaler and json.Unmarshaler and interfaces.\nvar (\n\t_ Request          = (*Call)(nil)\n\t_ json.Marshaler   = (*Call)(nil)\n\t_ json.Unmarshaler = (*Call)(nil)\n)\n\n// NewCall constructs a new Call message for the supplied ID, method and\n// parameters.\nfunc NewCall(id ID, method string, params any) (*Call, error) {\n\tp, merr := marshalInterface(params)\n\treq := &Call{\n\t\tid:     id,\n\t\tmethod: method,\n\t\tparams: p,\n\t}\n\treturn req, merr\n}\n\n// ID returns the current call id.\nfunc (c *Call) ID() ID { return c.id }\n\n// Method implements Request.\nfunc (c *Call) Method() string { return c.method }\n\n// Params implements Request.\nfunc (c *Call) Params() json.RawMessage { return c.params }\n\n// jsonrpc2Message implements Request.\nfunc (Call) jsonrpc2Message() {}\n\n// jsonrpc2Request implements Request.\nfunc (Call) jsonrpc2Request() {}\n\n// MarshalJSON implements json.Marshaler.\nfunc (c Call) MarshalJSON() ([]byte, error) {\n\treq := wireRequest{\n\t\tMethod: c.method,\n\t\tParams: &c.params,\n\t\tID:     &c.id,\n\t}\n\tdata, err := json.Marshal(req)\n\tif err != nil {\n\t\treturn data, fmt.Errorf(\"marshaling call: %w\", err)\n\t}\n\n\treturn data, nil\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (c *Call) UnmarshalJSON(data []byte) error {\n\tvar req wireRequest\n\tdec := json.NewDecoder(bytes.NewReader(data))\n\tif err := dec.Decode(&req); err != nil {\n\t\treturn fmt.Errorf(\"unmarshaling call: %w\", err)\n\t}\n\n\tc.method = req.Method\n\tif req.Params != nil {\n\t\tc.params = *req.Params\n\t}\n\tif req.ID != nil {\n\t\tc.id = *req.ID\n\t}\n\n\treturn nil\n}\n\n// Response is a reply to a Request.\n//\n// It will have the same ID as the call it is a response to.\ntype Response struct {\n\t// result is the content of the response.\n\tresult json.RawMessage\n\t// err is set only if the call failed.\n\terr error\n\t// ID of the request this is a response to.\n\tid ID\n}\n\n// make sure a Response implements the Message, json.Marshaler and json.Unmarshaler and interfaces.\nvar (\n\t_ Message          = (*Response)(nil)\n\t_ json.Marshaler   = (*Response)(nil)\n\t_ json.Unmarshaler = (*Response)(nil)\n)\n\n// NewResponse constructs a new Response message that is a reply to the\n// supplied. If err is set result may be ignored.\nfunc NewResponse(id ID, result any, err error) (*Response, error) {\n\tr, merr := marshalInterface(result)\n\tresp := &Response{\n\t\tid:     id,\n\t\tresult: r,\n\t\terr:    err,\n\t}\n\treturn resp, merr\n}\n\n// ID returns the current response id.\nfunc (r *Response) ID() ID { return r.id }\n\n// Result returns the Response result.\nfunc (r *Response) Result() json.RawMessage { return r.result }\n\n// Err returns the Response error.\nfunc (r *Response) Err() error { return r.err }\n\n// jsonrpc2Message implements Message.\nfunc (r *Response) jsonrpc2Message() {}\n\n// MarshalJSON implements json.Marshaler.\nfunc (r Response) MarshalJSON() ([]byte, error) {\n\tresp := &wireResponse{\n\t\tError: toError(r.err),\n\t\tID:    &r.id,\n\t}\n\tif resp.Error == nil {\n\t\tresp.Result = &r.result\n\t}\n\n\tdata, err := json.Marshal(resp)\n\tif err != nil {\n\t\treturn data, fmt.Errorf(\"marshaling notification: %w\", err)\n\t}\n\n\treturn data, nil\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (r *Response) UnmarshalJSON(data []byte) error {\n\tvar resp wireResponse\n\tdec := json.NewDecoder(bytes.NewReader(data))\n\tif err := dec.Decode(&resp); err != nil {\n\t\treturn fmt.Errorf(\"unmarshaling jsonrpc response: %w\", err)\n\t}\n\n\tif resp.Result != nil {\n\t\tr.result = *resp.Result\n\t}\n\tif resp.Error != nil {\n\t\tr.err = resp.Error\n\t}\n\tif resp.ID != nil {\n\t\tr.id = *resp.ID\n\t}\n\n\treturn nil\n}\n\nfunc toError(err error) *Error {\n\tif err == nil {\n\t\t// no error, the response is complete\n\t\treturn nil\n\t}\n\n\tvar wrapped *Error\n\tif errors.As(err, &wrapped) {\n\t\t// already a wire error, just use it\n\t\treturn wrapped\n\t}\n\n\tresult := &Error{Message: err.Error()}\n\tif errors.As(err, &wrapped) {\n\t\t// if we wrapped a wire error, keep the code from the wrapped error\n\t\t// but the message from the outer error\n\t\tresult.Code = wrapped.Code\n\t}\n\n\treturn result\n}\n\n// Notification is a request for which a response cannot occur, and as such\n// it has not ID.\ntype Notification struct {\n\t// Method is a string containing the method name to invoke.\n\tmethod string\n\n\tparams json.RawMessage\n}\n\n// make sure a Notification implements the Request, json.Marshaler and json.Unmarshaler and interfaces.\nvar (\n\t_ Request          = (*Notification)(nil)\n\t_ json.Marshaler   = (*Notification)(nil)\n\t_ json.Unmarshaler = (*Notification)(nil)\n)\n\n// NewNotification constructs a new Notification message for the supplied\n// method and parameters.\nfunc NewNotification(method string, params any) (*Notification, error) {\n\tp, merr := marshalInterface(params)\n\tnotify := &Notification{\n\t\tmethod: method,\n\t\tparams: p,\n\t}\n\treturn notify, merr\n}\n\n// Method implements Request.\nfunc (n *Notification) Method() string { return n.method }\n\n// Params implements Request.\nfunc (n *Notification) Params() json.RawMessage { return n.params }\n\n// jsonrpc2Message implements Request.\nfunc (Notification) jsonrpc2Message() {}\n\n// jsonrpc2Request implements Request.\nfunc (Notification) jsonrpc2Request() {}\n\n// MarshalJSON implements json.Marshaler.\nfunc (n Notification) MarshalJSON() ([]byte, error) {\n\treq := wireRequest{\n\t\tMethod: n.method,\n\t\tParams: &n.params,\n\t}\n\tdata, err := json.Marshal(req)\n\tif err != nil {\n\t\treturn data, fmt.Errorf(\"marshaling notification: %w\", err)\n\t}\n\n\treturn data, nil\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (n *Notification) UnmarshalJSON(data []byte) error {\n\tvar req wireRequest\n\tdec := json.NewDecoder(bytes.NewReader(data))\n\tif err := dec.Decode(&req); err != nil {\n\t\treturn fmt.Errorf(\"unmarshaling notification: %w\", err)\n\t}\n\n\tn.method = req.Method\n\tif req.Params != nil {\n\t\tn.params = *req.Params\n\t}\n\n\treturn nil\n}\n\n// DecodeMessage decodes data to Message.\nfunc DecodeMessage(data []byte) (Message, error) {\n\tvar msg combined\n\tdec := json.NewDecoder(bytes.NewReader(data))\n\tif err := dec.Decode(&msg); err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshaling jsonrpc message: %w\", err)\n\t}\n\n\tif msg.Method == \"\" {\n\t\t// no method, should be a response\n\t\tif msg.ID == nil {\n\t\t\treturn nil, ErrInvalidRequest\n\t\t}\n\n\t\tresp := &Response{\n\t\t\tid: *msg.ID,\n\t\t}\n\t\tif msg.Error != nil {\n\t\t\tresp.err = msg.Error\n\t\t}\n\t\tif msg.Result != nil {\n\t\t\tresp.result = *msg.Result\n\t\t}\n\n\t\treturn resp, nil\n\t}\n\n\t// has a method, must be a request\n\tif msg.ID == nil {\n\t\t// request with no ID is a notify\n\t\tnotify := &Notification{\n\t\t\tmethod: msg.Method,\n\t\t}\n\t\tif msg.Params != nil {\n\t\t\tnotify.params = *msg.Params\n\t\t}\n\n\t\treturn notify, nil\n\t}\n\n\t// request with an ID, must be a call\n\tcall := &Call{\n\t\tmethod: msg.Method,\n\t\tid:     *msg.ID,\n\t}\n\tif msg.Params != nil {\n\t\tcall.params = *msg.Params\n\t}\n\n\treturn call, nil\n}\n\n// marshalInterface marshal obj to json.RawMessage.\nfunc marshalInterface(obj any) (json.RawMessage, error) {\n\tdata, err := json.Marshal(obj)\n\tif err != nil {\n\t\treturn json.RawMessage{}, fmt.Errorf(\"failed to marshal json: %w\", err)\n\t}\n\treturn json.RawMessage(data), nil\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/serve.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"time\"\n)\n\n// NOTE: This file provides an experimental API for serving multiple remote\n// jsonrpc2 clients over the network. For now, it is intentionally similar to\n// net/http, but that may change in the future as we figure out the correct\n// semantics.\n\n// StreamServer is used to serve incoming jsonrpc2 clients communicating over\n// a newly created connection.\ntype StreamServer interface {\n\tServeStream(context.Context, Conn) error\n}\n\n// ServerFunc is an adapter that implements the StreamServer interface\n// using an ordinary function.\ntype ServerFunc func(context.Context, Conn) error\n\n// ServeStream implements StreamServer.\n//\n// ServeStream calls f(ctx, s).\nfunc (f ServerFunc) ServeStream(ctx context.Context, c Conn) error {\n\treturn f(ctx, c)\n}\n\n// HandlerServer returns a StreamServer that handles incoming streams using the\n// provided handler.\nfunc HandlerServer(h Handler) StreamServer {\n\treturn ServerFunc(func(ctx context.Context, conn Conn) error {\n\t\tconn.Go(ctx, h)\n\t\t<-conn.Done()\n\t\treturn conn.Err()\n\t})\n}\n\n// ListenAndServe starts an jsonrpc2 server on the given address.\n//\n// If idleTimeout is non-zero, ListenAndServe exits after there are no clients for\n// this duration, otherwise it exits only on error.\nfunc ListenAndServe(ctx context.Context, network, addr string, server StreamServer, idleTimeout time.Duration) error {\n\tln, err := net.Listen(network, addr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to listen %s:%s: %w\", network, addr, err)\n\t}\n\tdefer func() {\n\t\t_ = ln.Close()\n\t}()\n\n\tif network == \"unix\" {\n\t\tdefer func() { _ = os.Remove(addr) }()\n\t}\n\n\treturn Serve(ctx, ln, server, idleTimeout)\n}\n\n// Serve accepts incoming connections from the network, and handles them using\n// the provided server. If idleTimeout is non-zero, ListenAndServe exits after\n// there are no clients for this duration, otherwise it exits only on error.\nfunc Serve(ctx context.Context, ln net.Listener, server StreamServer, idleTimeout time.Duration) error {\n\tctx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\t// Max duration: ~290 years; surely that's long enough.\n\tconst forever = 1<<63 - 1\n\tif idleTimeout <= 0 {\n\t\tidleTimeout = forever\n\t}\n\tconnTimer := time.NewTimer(idleTimeout)\n\n\tnewConns := make(chan net.Conn)\n\tdoneListening := make(chan error)\n\tclosedConns := make(chan error)\n\n\tgo func() {\n\t\tfor {\n\t\t\tnc, err := ln.Accept()\n\t\t\tif err != nil {\n\t\t\t\tselect {\n\t\t\t\tcase doneListening <- fmt.Errorf(\"accept: %w\", err):\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tnewConns <- nc\n\t\t}\n\t}()\n\n\tactiveConns := 0\n\tfor {\n\t\tselect {\n\t\tcase netConn := <-newConns:\n\t\t\tactiveConns++\n\t\t\tconnTimer.Stop()\n\t\t\tstream := NewStream(netConn)\n\t\t\tgo func() {\n\t\t\t\tconn := NewConn(stream)\n\t\t\t\tclosedConns <- server.ServeStream(ctx, conn)\n\t\t\t\t_ = stream.Close()\n\t\t\t}()\n\n\t\tcase err := <-doneListening:\n\t\t\treturn err\n\n\t\tcase <-closedConns:\n\t\t\t// if !isClosingError(err) {\n\t\t\t// }\n\n\t\t\tactiveConns--\n\t\t\tif activeConns == 0 {\n\t\t\t\tconnTimer.Reset(idleTimeout)\n\t\t\t}\n\n\t\tcase <-connTimer.C:\n\t\t\treturn ErrIdleTimeout\n\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/serve_test.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n)\n\nfunc TestIdleTimeout(t *testing.T) {\n\tctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n\tdefer cancel()\n\n\tln, err := net.Listen(\"tcp\", \"localhost:0\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer func() {\n\t\t_ = ln.Close()\n\t}()\n\n\tconnect := func() net.Conn {\n\t\tconn, err := net.DialTimeout(\"tcp\", ln.Addr().String(), 5*time.Second)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\treturn conn\n\t}\n\n\tserver := jsonrpc2.HandlerServer(jsonrpc2.MethodNotFoundHandler)\n\tvar (\n\t\trunErr error\n\t\twg     sync.WaitGroup\n\t)\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\trunErr = jsonrpc2.Serve(ctx, ln, server, 100*time.Millisecond)\n\t}()\n\n\t// Exercise some connection/disconnection patterns, and then assert that when\n\t// our timer fires, the server exits.\n\tconn1 := connect()\n\tconn2 := connect()\n\t_ = conn1.Close()\n\t_ = conn2.Close()\n\tconn3 := connect()\n\t_ = conn3.Close()\n\n\twg.Wait()\n\n\tif !errors.Is(runErr, jsonrpc2.ErrIdleTimeout) {\n\t\tt.Errorf(\"run() returned error %v, want %v\", runErr, jsonrpc2.ErrIdleTimeout)\n\t}\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/stream.go",
    "content": "// SPDX-FileCopyrightText: 2018 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"encoding/json\"\n)\n\nconst (\n\t// HdrContentLength is the HTTP header name of the length of the content part in bytes. This header is required.\n\t// This entity header indicates the size of the entity-body, in bytes, sent to the recipient.\n\t//\n\t// RFC 7230, section 3.3.2: Content-Length:\n\t//  https://tools.ietf.org/html/rfc7230#section-3.3.2\n\tHdrContentLength = \"Content-Length\"\n\n\t// HeaderContentType is the mime type of the content part. Defaults to \"application/vscode-jsonrpc; charset=utf-8\".\n\t// This entity header is used to indicate the media type of the resource.\n\t//\n\t// RFC 7231, section 3.1.1.5: Content-Type:\n\t//  https://tools.ietf.org/html/rfc7231#section-3.1.1.5\n\tHdrContentType = \"Content-Type\"\n\n\t// HeaderContentSeparator is the header and content part separator.\n\tHdrContentSeparator = \"\\r\\n\\r\\n\"\n)\n\n// Framer wraps a network connection up into a Stream.\n//\n// It is responsible for the framing and encoding of messages into wire form.\n// NewRawStream and NewStream are implementations of a Framer.\ntype Framer func(conn io.ReadWriteCloser) Stream\n\n// Stream abstracts the transport mechanics from the JSON RPC protocol.\n//\n// A Conn reads and writes messages using the stream it was provided on\n// construction, and assumes that each call to Read or Write fully transfers\n// a single message, or returns an error.\n//\n// A stream is not safe for concurrent use, it is expected it will be used by\n// a single Conn in a safe manner.\ntype Stream interface {\n\t// Read gets the next message from the stream.\n\tRead(context.Context) (Message, int64, error)\n\n\t// Write sends a message to the stream.\n\tWrite(context.Context, Message) (int64, error)\n\n\t// Close closes the connection.\n\t// Any blocked Read or Write operations will be unblocked and return errors.\n\tClose() error\n}\n\ntype rawStream struct {\n\tconn io.ReadWriteCloser\n\tin   *json.Decoder\n}\n\n// NewRawStream returns a Stream built on top of a io.ReadWriteCloser.\n//\n// The messages are sent with no wrapping, and rely on json decode consistency\n// to determine message boundaries.\nfunc NewRawStream(conn io.ReadWriteCloser) Stream {\n\treturn &rawStream{\n\t\tconn: conn,\n\t\tin:   json.NewDecoder(conn), // TODO(zchee): why test fail using segmentio json.Decoder?\n\t}\n}\n\n// Read implements Stream.Read.\nfunc (s *rawStream) Read(ctx context.Context) (Message, int64, error) {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, 0, ctx.Err()\n\tdefault:\n\t}\n\n\tvar raw json.RawMessage\n\tif err := s.in.Decode(&raw); err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"decoding raw message: %w\", err)\n\t}\n\n\tmsg, err := DecodeMessage(raw)\n\treturn msg, int64(len(raw)), err\n}\n\n// Write implements Stream.Write.\nfunc (s *rawStream) Write(ctx context.Context, msg Message) (int64, error) {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn 0, ctx.Err()\n\tdefault:\n\t}\n\n\tdata, err := json.Marshal(msg)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"marshaling message: %w\", err)\n\t}\n\n\tn, err := s.conn.Write(data)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"write to stream: %w\", err)\n\t}\n\n\treturn int64(n), nil\n}\n\n// Close implements Stream.Close.\nfunc (s *rawStream) Close() error {\n\treturn s.conn.Close()\n}\n\ntype stream struct {\n\tconn io.ReadWriteCloser\n\tin   *bufio.Reader\n}\n\n// NewStream returns a Stream built on top of a io.ReadWriteCloser.\n//\n// The messages are sent with HTTP content length and MIME type headers.\n// This is the format used by LSP and others.\nfunc NewStream(conn io.ReadWriteCloser) Stream {\n\treturn &stream{\n\t\tconn: conn,\n\t\tin:   bufio.NewReader(conn),\n\t}\n}\n\n// Read implements Stream.Read.\nfunc (s *stream) Read(ctx context.Context) (Message, int64, error) {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, 0, ctx.Err()\n\tdefault:\n\t}\n\n\tvar total int64\n\tvar length int64\n\t// read the header, stop on the first empty line\n\tfor {\n\t\tline, err := s.in.ReadString('\\n')\n\t\ttotal += int64(len(line))\n\t\tif err != nil {\n\t\t\treturn nil, total, fmt.Errorf(\"failed reading header line: %w\", err)\n\t\t}\n\n\t\tline = strings.TrimSpace(line)\n\t\t// check we have a header line\n\t\tif line == \"\" {\n\t\t\tbreak\n\t\t}\n\n\t\tcolon := strings.IndexRune(line, ':')\n\t\tif colon < 0 {\n\t\t\treturn nil, total, fmt.Errorf(\"invalid header line %q\", line)\n\t\t}\n\n\t\tname, value := line[:colon], strings.TrimSpace(line[colon+1:])\n\t\tswitch name {\n\t\tcase HdrContentLength:\n\t\t\tif length, err = strconv.ParseInt(value, 10, 32); err != nil {\n\t\t\t\treturn nil, total, fmt.Errorf(\"failed parsing %s: %v: %w\", HdrContentLength, value, err)\n\t\t\t}\n\t\t\tif length <= 0 {\n\t\t\t\treturn nil, total, fmt.Errorf(\"invalid %s: %v\", HdrContentLength, length)\n\t\t\t}\n\t\tdefault:\n\t\t\t// ignoring unknown headers\n\t\t}\n\t}\n\n\tif length == 0 {\n\t\treturn nil, total, fmt.Errorf(\"missing %s header\", HdrContentLength)\n\t}\n\n\tdata := make([]byte, length)\n\tif _, err := io.ReadFull(s.in, data); err != nil {\n\t\treturn nil, total, fmt.Errorf(\"read full of data: %w\", err)\n\t}\n\n\ttotal += length\n\tmsg, err := DecodeMessage(data)\n\treturn msg, total, err\n}\n\n// Write implements Stream.Write.\nfunc (s *stream) Write(ctx context.Context, msg Message) (int64, error) {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn 0, ctx.Err()\n\tdefault:\n\t}\n\n\tdata, err := json.Marshal(msg)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"marshaling message: %w\", err)\n\t}\n\n\tn, err := fmt.Fprintf(s.conn, \"%s: %v%s\", HdrContentLength, len(data), HdrContentSeparator)\n\ttotal := int64(n)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"write data to conn: %w\", err)\n\t}\n\n\tn, err = s.conn.Write(data)\n\ttotal += int64(n)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"write data to conn: %w\", err)\n\t}\n\n\treturn total, nil\n}\n\n// Close implements Stream.Close.\nfunc (s *stream) Close() error {\n\treturn s.conn.Close()\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/wire.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2\n\nimport (\n\t\"fmt\"\n\n\t\"encoding/json\"\n)\n\n// Version represents a JSON-RPC version.\nconst Version = \"2.0\"\n\n// version is a special 0 sized struct that encodes as the jsonrpc version tag.\n//\n// It will fail during decode if it is not the correct version tag in the stream.\ntype version struct{}\n\n// compile time check whether the version implements a json.Marshaler and json.Unmarshaler interfaces.\nvar (\n\t_ json.Marshaler   = (*version)(nil)\n\t_ json.Unmarshaler = (*version)(nil)\n)\n\n// MarshalJSON implements json.Marshaler.\nfunc (version) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(Version)\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (version) UnmarshalJSON(data []byte) error {\n\tversion := \"\"\n\tif err := json.Unmarshal(data, &version); err != nil {\n\t\treturn fmt.Errorf(\"failed to Unmarshal: %w\", err)\n\t}\n\tif version != Version {\n\t\treturn fmt.Errorf(\"invalid RPC version %v\", version)\n\t}\n\treturn nil\n}\n\n// ID is a Request identifier.\n//\n// Only one of either the Name or Number members will be set, using the\n// number form if the Name is the empty string.\ntype ID struct {\n\tname   string\n\tnumber int32\n}\n\n// compile time check whether the ID implements a fmt.Formatter, json.Marshaler and json.Unmarshaler interfaces.\nvar (\n\t_ fmt.Formatter    = (*ID)(nil)\n\t_ json.Marshaler   = (*ID)(nil)\n\t_ json.Unmarshaler = (*ID)(nil)\n)\n\n// NewNumberID returns a new number request ID.\nfunc NewNumberID(v int32) ID { return ID{number: v} }\n\n// NewStringID returns a new string request ID.\nfunc NewStringID(v string) ID { return ID{name: v} }\n\n// Format writes the ID to the formatter.\n//\n// If the rune is q the representation is non ambiguous,\n// string forms are quoted, number forms are preceded by a #.\nfunc (id ID) Format(f fmt.State, r rune) {\n\tnumF, strF := `%d`, `%s`\n\tif r == 'q' {\n\t\tnumF, strF = `#%d`, `%q`\n\t}\n\n\tswitch {\n\tcase id.name != \"\":\n\t\t_, _ = fmt.Fprintf(f, strF, id.name)\n\tdefault:\n\t\t_, _ = fmt.Fprintf(f, numF, id.number)\n\t}\n}\n\n// MarshalJSON implements json.Marshaler.\nfunc (id *ID) MarshalJSON() ([]byte, error) {\n\tif id.name != \"\" {\n\t\treturn json.Marshal(id.name)\n\t}\n\treturn json.Marshal(id.number)\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (id *ID) UnmarshalJSON(data []byte) error {\n\t*id = ID{}\n\tif err := json.Unmarshal(data, &id.number); err == nil {\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &id.name)\n}\n\n// wireRequest is sent to a server to represent a Call or Notify operaton.\ntype wireRequest struct {\n\t// VersionTag is always encoded as the string \"2.0\"\n\tVersionTag version `json:\"jsonrpc\"`\n\t// Method is a string containing the method name to invoke.\n\tMethod string `json:\"method\"`\n\t// Params is either a struct or an array with the parameters of the method.\n\tParams *json.RawMessage `json:\"params,omitempty\"`\n\t// The id of this request, used to tie the Response back to the request.\n\t// Will be either a string or a number. If not set, the Request is a notify,\n\t// and no response is possible.\n\tID *ID `json:\"id,omitempty\"`\n}\n\n// wireResponse is a reply to a Request.\n//\n// It will always have the ID field set to tie it back to a request, and will\n// have either the Result or Error fields set depending on whether it is a\n// success or failure wireResponse.\ntype wireResponse struct {\n\t// VersionTag is always encoded as the string \"2.0\"\n\tVersionTag version `json:\"jsonrpc\"`\n\t// Result is the response value, and is required on success.\n\tResult *json.RawMessage `json:\"result,omitempty\"`\n\t// Error is a structured error response if the call fails.\n\tError *Error `json:\"error,omitempty\"`\n\t// ID must be set and is the identifier of the Request this is a response to.\n\tID *ID `json:\"id,omitempty\"`\n}\n\n// combined has all the fields of both Request and Response.\n//\n// We can decode this and then work out which it is.\ntype combined struct {\n\tVersionTag version          `json:\"jsonrpc\"`\n\tID         *ID              `json:\"id,omitempty\"`\n\tMethod     string           `json:\"method\"`\n\tParams     *json.RawMessage `json:\"params,omitempty\"`\n\tResult     *json.RawMessage `json:\"result,omitempty\"`\n\tError      *Error           `json:\"error,omitempty\"`\n}\n"
  },
  {
    "path": "lsp/jsonrpc2/wire_test.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage jsonrpc2_test\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n)\n\nvar wireIDTestData = []struct {\n\tname    string\n\tid      jsonrpc2.ID\n\tencoded []byte\n\tplain   string\n\tquoted  string\n}{\n\t{\n\t\tname:    `empty`,\n\t\tencoded: []byte(`0`),\n\t\tplain:   `0`,\n\t\tquoted:  `#0`,\n\t}, {\n\t\tname:    `number`,\n\t\tid:      jsonrpc2.NewNumberID(43),\n\t\tencoded: []byte(`43`),\n\t\tplain:   `43`,\n\t\tquoted:  `#43`,\n\t}, {\n\t\tname:    `string`,\n\t\tid:      jsonrpc2.NewStringID(\"life\"),\n\t\tencoded: []byte(`\"life\"`),\n\t\tplain:   `life`,\n\t\tquoted:  `\"life\"`,\n\t},\n}\n\nfunc TestIDFormat(t *testing.T) {\n\tt.Parallel()\n\n\tfor _, tt := range wireIDTestData {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := fmt.Sprint(tt.id); got != tt.plain {\n\t\t\t\tt.Errorf(\"got %s expected %s\", got, tt.plain)\n\t\t\t}\n\t\t\tif got := fmt.Sprintf(\"%q\", tt.id); got != tt.quoted {\n\t\t\t\tt.Errorf(\"got %s want %s\", got, tt.quoted)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIDEncode(t *testing.T) {\n\tt.Parallel()\n\n\tfor _, tt := range wireIDTestData {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tdata, err := json.Marshal(&tt.id)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tcheckJSON(t, data, tt.encoded)\n\t\t})\n\t}\n}\n\nfunc TestIDDecode(t *testing.T) {\n\tt.Parallel()\n\n\tfor _, tt := range wireIDTestData {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tvar got *jsonrpc2.ID\n\t\t\tdec := json.NewDecoder(bytes.NewReader(tt.encoded))\n\t\t\tif err := dec.Decode(&got); err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\n\t\t\tif reflect.ValueOf(&got).IsZero() {\n\t\t\t\tt.Fatalf(\"got nil want %s\", tt.id)\n\t\t\t}\n\n\t\t\tif *got != tt.id {\n\t\t\t\tt.Fatalf(\"got %s want %s\", got, tt.id)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestErrorEncode(t *testing.T) {\n\tt.Parallel()\n\n\tb, err := json.Marshal(jsonrpc2.NewError(0, \"\"))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tcheckJSON(t, b, []byte(`{\n\t\t\"code\": 0,\n\t\t\"message\": \"\"\n\t}`))\n}\n\nfunc TestErrorResponse(t *testing.T) {\n\tt.Parallel()\n\n\t// originally reported in #39719, this checks that result is not present if\n\t// it is an error response\n\tr, _ := jsonrpc2.NewResponse(jsonrpc2.NewNumberID(3), nil, fmt.Errorf(\"computing fix edits\"))\n\tdata, err := json.Marshal(r)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tcheckJSON(t, data, []byte(`{\n\t\t\"jsonrpc\":\"2.0\",\n\t\t\"error\":{\n\t\t\t\"code\":0,\n\t\t\t\"message\":\"computing fix edits\"\n\t\t},\n\t\t\"id\":3\n\t}`))\n}\n\nfunc checkJSON(t *testing.T, got, want []byte) {\n\tt.Helper()\n\n\t// compare the compact form, to allow for formatting differences\n\tg := &bytes.Buffer{}\n\tif err := json.Compact(g, got); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tw := &bytes.Buffer{}\n\tif err := json.Compact(w, want); err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif g.String() != w.String() {\n\t\tt.Fatalf(\"Got:\\n%s\\nWant:\\n%s\", g, w)\n\t}\n}\n"
  },
  {
    "path": "lsp/protocol/base.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// CancelParams params of cancelRequest.\ntype CancelParams struct {\n\t// ID is the request id to cancel.\n\tID any `json:\"id\"` // int32 | string\n}\n\n// ProgressParams params of Progress netification.\n//\n// @since 3.15.0.\ntype ProgressParams struct {\n\t// Token is the progress token provided by the client or server.\n\tToken ProgressToken `json:\"token\"`\n\n\t// Value is the progress data.\n\tValue any `json:\"value\"`\n}\n\n// ProgressToken is the progress token provided by the client or server.\n//\n// @since 3.15.0.\ntype ProgressToken struct {\n\tname   string\n\tnumber int32\n}\n\n// compile time check whether the ProgressToken implements a fmt.Formatter, fmt.Stringer, json.Marshaler and json.Unmarshaler interfaces.\nvar (\n\t_ fmt.Formatter    = (*ProgressToken)(nil)\n\t_ fmt.Stringer     = (*ProgressToken)(nil)\n\t_ json.Marshaler   = (*ProgressToken)(nil)\n\t_ json.Unmarshaler = (*ProgressToken)(nil)\n)\n\n// NewProgressToken returns a new ProgressToken.\nfunc NewProgressToken(s string) *ProgressToken {\n\treturn &ProgressToken{name: s}\n}\n\n// NewNumberProgressToken returns a new number ProgressToken.\nfunc NewNumberProgressToken(n int32) *ProgressToken {\n\treturn &ProgressToken{number: n}\n}\n\n// Format writes the ProgressToken to the formatter.\n//\n// If the rune is q the representation is non ambiguous,\n// string forms are quoted.\nfunc (v ProgressToken) Format(f fmt.State, r rune) {\n\tconst numF = `%d`\n\tstrF := `%s`\n\tif r == 'q' {\n\t\tstrF = `%q`\n\t}\n\n\tswitch {\n\tcase v.name != \"\":\n\t\t_, _ = fmt.Fprintf(f, strF, v.name)\n\tdefault:\n\t\t_, _ = fmt.Fprintf(f, numF, v.number)\n\t}\n}\n\n// String returns a string representation of the ProgressToken.\nfunc (v ProgressToken) String() string {\n\treturn fmt.Sprint(v)\n}\n\n// MarshalJSON implements json.Marshaler.\nfunc (v *ProgressToken) MarshalJSON() ([]byte, error) {\n\tif v.name != \"\" {\n\t\treturn json.Marshal(v.name)\n\t}\n\n\treturn json.Marshal(v.number)\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (v *ProgressToken) UnmarshalJSON(data []byte) error {\n\t*v = ProgressToken{}\n\tif err := json.Unmarshal(data, &v.number); err == nil {\n\t\treturn nil\n\t}\n\n\treturn json.Unmarshal(data, &v.name)\n}\n"
  },
  {
    "path": "lsp/protocol/base_test.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n)\n\nfunc TestCancelParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst want = `{\"id\":\"testID\"}`\n\twantType := CancelParams{\n\t\tID: \"testID\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CancelParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CancelParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CancelParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestProgressParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst wantWorkDoneToken = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\tconst want = `{\"token\":\"` + wantWorkDoneToken + `\",\"value\":\"testValue\"}`\n\n\ttoken := NewProgressToken(wantWorkDoneToken)\n\twantType := ProgressParams{\n\t\tToken: *token,\n\t\tValue: \"testValue\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ProgressParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ProgressParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ProgressParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreFields(ProgressParams{}, \"Token\")); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif token := got.Token; !reflect.ValueOf(token).IsZero() {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(token), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/basic.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\n// DocumentURI represents the URI of a document.\n//\n// Many of the interfaces contain fields that correspond to the URI of a document.\n// For clarity, the type of such a field is declared as a DocumentURI.\n// Over the wire, it will still be transferred as a string, but this guarantees\n// that the contents of that string can be parsed as a valid URI.\ntype DocumentURI = uri.URI\n\n// URI a tagging interface for normal non document URIs.\n//\n// @since 3.16.0.\ntype URI = uri.URI\n\n// EOL denotes represents the character offset.\nvar EOL = []string{\"\\n\", \"\\r\\n\", \"\\r\"}\n\n// Position represents a text document expressed as zero-based line and zero-based character offset.\n//\n// The offsets are based on a UTF-16 string representation.\n// So a string of the form \"a𐐀b\" the character offset of the character \"a\" is 0,\n// the character offset of \"𐐀\" is 1 and the character offset of \"b\" is 3 since 𐐀 is represented using two code\n// units in UTF-16.\n//\n// Positions are line end character agnostic. So you can not specify a position that\n// denotes \"\\r|\\n\" or \"\\n|\" where \"|\" represents the character offset.\n//\n// Position is between two characters like an \"insert\" cursor in a editor.\n// Special values like for example \"-1\" to denote the end of a line are not supported.\ntype Position struct {\n\t// Line position in a document (zero-based).\n\t//\n\t// If a line number is greater than the number of lines in a document, it defaults back to the number of lines in\n\t// the document.\n\t// If a line number is negative, it defaults to 0.\n\tLine uint32 `json:\"line\"`\n\n\t// Character offset on a line in a document (zero-based).\n\t//\n\t// Assuming that the line is represented as a string, the Character value represents the gap between the\n\t// \"character\" and \"character + 1\".\n\t//\n\t// If the character value is greater than the line length it defaults back to the line length.\n\t// If a line number is negative, it defaults to 0.\n\tCharacter uint32 `json:\"character\"`\n}\n\n// Range represents a text document expressed as (zero-based) start and end positions.\n//\n// A range is comparable to a selection in an editor. Therefore the end position is exclusive.\n// If you want to specify a range that contains a line including the line ending character(s) then use an end position\n// denoting the start of the next line.\ntype Range struct {\n\t// Start is the range's start position.\n\tStart Position `json:\"start\"`\n\n\t// End is the range's end position.\n\tEnd Position `json:\"end\"`\n}\n\n// Location represents a location inside a resource, such as a line inside a text file.\ntype Location struct {\n\tURI   DocumentURI `json:\"uri\"`\n\tRange Range       `json:\"range\"`\n}\n\n// LocationLink represents a link between a source and a target location.\ntype LocationLink struct {\n\t// OriginSelectionRange span of the origin of this link.\n\t//\n\t// Used as the underlined span for mouse interaction. Defaults to the word range at the mouse position.\n\tOriginSelectionRange *Range `json:\"originSelectionRange,omitempty\"`\n\n\t// TargetURI is the target resource identifier of this link.\n\tTargetURI DocumentURI `json:\"targetUri\"`\n\n\t// TargetRange is the full target range of this link.\n\t//\n\t// If the target for example is a symbol then target range is the range enclosing this symbol not including\n\t// leading/trailing whitespace but everything else like comments.\n\t//\n\t// This information is typically used to highlight the range in the editor.\n\tTargetRange Range `json:\"targetRange\"`\n\n\t// TargetSelectionRange is the range that should be selected and revealed when this link is being followed,\n\t// e.g the name of a function.\n\t//\n\t// Must be contained by the the TargetRange. See also DocumentSymbol#range\n\tTargetSelectionRange Range `json:\"targetSelectionRange\"`\n}\n\n// Command represents a reference to a command. Provides a title which will be used to represent a command in the UI.\n//\n// Commands are identified by a string identifier.\n// The recommended way to handle commands is to implement their execution on the server side if the client and\n// server provides the corresponding capabilities.\n//\n// Alternatively the tool extension code could handle the command. The protocol currently doesn't specify\n// a set of well-known commands.\ntype Command struct {\n\t// Title of the command, like `save`.\n\tTitle string `json:\"title\"`\n\n\t// Command is the identifier of the actual command handler.\n\tCommand string `json:\"command\"`\n\n\t// Arguments that the command handler should be invoked with.\n\tArguments []any `json:\"arguments,omitempty\"`\n}\n\n// TextEdit is a textual edit applicable to a text document.\ntype TextEdit struct {\n\t// Range is the range of the text document to be manipulated.\n\t//\n\t// To insert text into a document create a range where start == end.\n\tRange Range `json:\"range\"`\n\n\t// NewText is the string to be inserted. For delete operations use an\n\t// empty string.\n\tNewText string `json:\"newText\"`\n}\n\n// ChangeAnnotation is the additional information that describes document changes.\n//\n// @since 3.16.0.\ntype ChangeAnnotation struct {\n\t// Label a human-readable string describing the actual change.\n\t// The string is rendered prominent in the user interface.\n\tLabel string `json:\"label\"`\n\n\t// NeedsConfirmation is a flag which indicates that user confirmation is needed\n\t// before applying the change.\n\tNeedsConfirmation bool `json:\"needsConfirmation,omitempty\"`\n\n\t// Description is a human-readable string which is rendered less prominent in\n\t// the user interface.\n\tDescription string `json:\"description,omitempty\"`\n}\n\n// ChangeAnnotationIdentifier an identifier referring to a change annotation managed by a workspace\n// edit.\n//\n// @since 3.16.0.\ntype ChangeAnnotationIdentifier string\n\n// AnnotatedTextEdit is a special text edit with an additional change annotation.\n//\n// @since 3.16.0.\ntype AnnotatedTextEdit struct {\n\tTextEdit\n\n\t// AnnotationID is the actual annotation identifier.\n\tAnnotationID ChangeAnnotationIdentifier `json:\"annotationId\"`\n}\n\n// TextDocumentEdit describes textual changes on a single text document.\n//\n// The TextDocument is referred to as a OptionalVersionedTextDocumentIdentifier to allow clients to check the\n// text document version before an edit is applied.\n//\n// TextDocumentEdit describes all changes on a version \"Si\" and after they are applied move the document to\n// version \"Si+1\".\n// So the creator of a TextDocumentEdit doesn't need to sort the array or do any kind of ordering. However the\n// edits must be non overlapping.\ntype TextDocumentEdit struct {\n\t// TextDocument is the text document to change.\n\tTextDocument OptionalVersionedTextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Edits is the edits to be applied.\n\t//\n\t// @since 3.16.0 - support for AnnotatedTextEdit.\n\t// This is guarded by the client capability Workspace.WorkspaceEdit.ChangeAnnotationSupport.\n\tEdits []TextEdit `json:\"edits\"` // []TextEdit | []AnnotatedTextEdit\n}\n\n// ResourceOperationKind is the file event type.\ntype ResourceOperationKind string\n\nconst (\n\t// CreateResourceOperation supports creating new files and folders.\n\tCreateResourceOperation ResourceOperationKind = \"create\"\n\n\t// RenameResourceOperation supports renaming existing files and folders.\n\tRenameResourceOperation ResourceOperationKind = \"rename\"\n\n\t// DeleteResourceOperation supports deleting existing files and folders.\n\tDeleteResourceOperation ResourceOperationKind = \"delete\"\n)\n\n// CreateFileOptions represents an options to create a file.\ntype CreateFileOptions struct {\n\t// Overwrite existing file. Overwrite wins over `ignoreIfExists`.\n\tOverwrite bool `json:\"overwrite,omitempty\"`\n\n\t// IgnoreIfExists ignore if exists.\n\tIgnoreIfExists bool `json:\"ignoreIfExists,omitempty\"`\n}\n\n// CreateFile represents a create file operation.\ntype CreateFile struct {\n\t// Kind a create.\n\tKind ResourceOperationKind `json:\"kind\"` // should be `create`\n\n\t// URI is the resource to create.\n\tURI DocumentURI `json:\"uri\"`\n\n\t// Options additional options.\n\tOptions *CreateFileOptions `json:\"options,omitempty\"`\n\n\t// AnnotationID an optional annotation identifier describing the operation.\n\t//\n\t// @since 3.16.0.\n\tAnnotationID ChangeAnnotationIdentifier `json:\"annotationId,omitempty\"`\n}\n\n// RenameFileOptions represents a rename file options.\ntype RenameFileOptions struct {\n\t// Overwrite target if existing. Overwrite wins over `ignoreIfExists`.\n\tOverwrite bool `json:\"overwrite,omitempty\"`\n\n\t// IgnoreIfExists ignores if target exists.\n\tIgnoreIfExists bool `json:\"ignoreIfExists,omitempty\"`\n}\n\n// RenameFile represents a rename file operation.\ntype RenameFile struct {\n\t// Kind a rename.\n\tKind ResourceOperationKind `json:\"kind\"` // should be `rename`\n\n\t// OldURI is the old (existing) location.\n\tOldURI DocumentURI `json:\"oldUri\"`\n\n\t// NewURI is the new location.\n\tNewURI DocumentURI `json:\"newUri\"`\n\n\t// Options rename options.\n\tOptions *RenameFileOptions `json:\"options,omitempty\"`\n\n\t// AnnotationID an optional annotation identifier describing the operation.\n\t//\n\t// @since 3.16.0.\n\tAnnotationID ChangeAnnotationIdentifier `json:\"annotationId,omitempty\"`\n}\n\n// DeleteFileOptions represents a delete file options.\ntype DeleteFileOptions struct {\n\t// Recursive delete the content recursively if a folder is denoted.\n\tRecursive bool `json:\"recursive,omitempty\"`\n\n\t// IgnoreIfNotExists ignore the operation if the file doesn't exist.\n\tIgnoreIfNotExists bool `json:\"ignoreIfNotExists,omitempty\"`\n}\n\n// DeleteFile represents a delete file operation.\ntype DeleteFile struct {\n\t// Kind is a delete.\n\tKind ResourceOperationKind `json:\"kind\"` // should be `delete`\n\n\t// URI is the file to delete.\n\tURI DocumentURI `json:\"uri\"`\n\n\t// Options delete options.\n\tOptions *DeleteFileOptions `json:\"options,omitempty\"`\n\n\t// AnnotationID an optional annotation identifier describing the operation.\n\t//\n\t// @since 3.16.0.\n\tAnnotationID ChangeAnnotationIdentifier `json:\"annotationId,omitempty\"`\n}\n\n// WorkspaceEdit represent a changes to many resources managed in the workspace.\n//\n// The edit should either provide changes or documentChanges.\n// If the client can handle versioned document edits and if documentChanges are present, the latter are preferred over\n// changes.\ntype WorkspaceEdit struct {\n\t// Changes holds changes to existing resources.\n\tChanges map[DocumentURI][]TextEdit `json:\"changes,omitempty\"`\n\n\t// DocumentChanges depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes\n\t// are either an array of `TextDocumentEdit`s to express changes to n different text documents\n\t// where each text document edit addresses a specific version of a text document. Or it can contain\n\t// above `TextDocumentEdit`s mixed with create, rename and delete file / folder operations.\n\t//\n\t// Whether a client supports versioned document edits is expressed via\n\t// `workspace.workspaceEdit.documentChanges` client capability.\n\t//\n\t// If a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then\n\t// only plain `TextEdit`s using the `changes` property are supported.\n\tDocumentChanges []TextDocumentEdit `json:\"documentChanges,omitempty\"`\n\n\t// ChangeAnnotations is a map of change annotations that can be referenced in\n\t// \"AnnotatedTextEdit\"s or create, rename and delete file / folder\n\t// operations.\n\t//\n\t// Whether clients honor this property depends on the client capability\n\t// \"workspace.changeAnnotationSupport\".\n\t//\n\t// @since 3.16.0.\n\tChangeAnnotations map[ChangeAnnotationIdentifier]ChangeAnnotation `json:\"changeAnnotations,omitempty\"`\n}\n\n// TextDocumentIdentifier indicates the using a URI. On the protocol level, URIs are passed as strings.\ntype TextDocumentIdentifier struct {\n\t// URI is the text document's URI.\n\tURI DocumentURI `json:\"uri\"`\n}\n\n// TextDocumentItem represent an item to transfer a text document from the client to the server.\ntype TextDocumentItem struct {\n\t// URI is the text document's URI.\n\tURI DocumentURI `json:\"uri\"`\n\n\t// LanguageID is the text document's language identifier.\n\tLanguageID LanguageIdentifier `json:\"languageId\"`\n\n\t// Version is the version number of this document (it will increase after each\n\t// change, including undo/redo).\n\tVersion int32 `json:\"version\"`\n\n\t// Text is the content of the opened text document.\n\tText string `json:\"text\"`\n}\n\n// LanguageIdentifier represent a text document's language identifier.\ntype LanguageIdentifier string\n\nconst (\n\t// ABAPLanguage ABAP Language.\n\tABAPLanguage LanguageIdentifier = \"abap\"\n\n\t// BatLanguage Windows Bat Language.\n\tBatLanguage LanguageIdentifier = \"bat\"\n\n\t// BibtexLanguage BibTeX Language.\n\tBibtexLanguage LanguageIdentifier = \"bibtex\"\n\n\t// ClojureLanguage Clojure Language.\n\tClojureLanguage LanguageIdentifier = \"clojure\"\n\n\t// CoffeescriptLanguage CoffeeScript Language.\n\tCoffeeScriptLanguage LanguageIdentifier = \"coffeescript\"\n\n\t// CLanguage C Language.\n\tCLanguage LanguageIdentifier = \"c\"\n\n\t// CppLanguage C++ Language.\n\tCppLanguage LanguageIdentifier = \"cpp\"\n\n\t// CsharpLanguage C# Language.\n\tCsharpLanguage LanguageIdentifier = \"csharp\"\n\n\t// CSSLanguage CSS Language.\n\tCSSLanguage LanguageIdentifier = \"css\"\n\n\t// DiffLanguage Diff Language.\n\tDiffLanguage LanguageIdentifier = \"diff\"\n\n\t// DartLanguage Dart Language.\n\tDartLanguage LanguageIdentifier = \"dart\"\n\n\t// DockerfileLanguage Dockerfile Language.\n\tDockerfileLanguage LanguageIdentifier = \"dockerfile\"\n\n\t// ElixirLanguage Elixir Language.\n\tElixirLanguage LanguageIdentifier = \"elixir\"\n\n\t// ErlangLanguage Erlang Language.\n\tErlangLanguage LanguageIdentifier = \"erlang\"\n\n\t// FsharpLanguage F# Language.\n\tFsharpLanguage LanguageIdentifier = \"fsharp\"\n\n\t// GitCommitLanguage Git Language.\n\tGitCommitLanguage LanguageIdentifier = \"git-commit\"\n\n\t// GitRebaseLanguage Git Language.\n\tGitRebaseLanguage LanguageIdentifier = \"git-rebase\"\n\n\t// GoLanguage Go Language.\n\tGoLanguage LanguageIdentifier = \"go\"\n\n\t// GroovyLanguage Groovy Language.\n\tGroovyLanguage LanguageIdentifier = \"groovy\"\n\n\t// HandlebarsLanguage Handlebars Language.\n\tHandlebarsLanguage LanguageIdentifier = \"handlebars\"\n\n\t// HTMLLanguage HTML Language.\n\tHTMLLanguage LanguageIdentifier = \"html\"\n\n\t// IniLanguage Ini Language.\n\tIniLanguage LanguageIdentifier = \"ini\"\n\n\t// JavaLanguage Java Language.\n\tJavaLanguage LanguageIdentifier = \"java\"\n\n\t// JavaScriptLanguage JavaScript Language.\n\tJavaScriptLanguage LanguageIdentifier = \"javascript\"\n\n\t// JavaScriptReactLanguage JavaScript React Language.\n\tJavaScriptReactLanguage LanguageIdentifier = \"javascriptreact\"\n\n\t// JSONLanguage JSON Language.\n\tJSONLanguage LanguageIdentifier = \"json\"\n\n\t// LatexLanguage LaTeX Language.\n\tLatexLanguage LanguageIdentifier = \"latex\"\n\n\t// LessLanguage Less Language.\n\tLessLanguage LanguageIdentifier = \"less\"\n\n\t// LuaLanguage Lua Language.\n\tLuaLanguage LanguageIdentifier = \"lua\"\n\n\t// MakefileLanguage Makefile Language.\n\tMakefileLanguage LanguageIdentifier = \"makefile\"\n\n\t// MarkdownLanguage Markdown Language.\n\tMarkdownLanguage LanguageIdentifier = \"markdown\"\n\n\t// ObjectiveCLanguage Objective-C Language.\n\tObjectiveCLanguage LanguageIdentifier = \"objective-c\"\n\n\t// ObjectiveCppLanguage Objective-C++ Language.\n\tObjectiveCppLanguage LanguageIdentifier = \"objective-cpp\"\n\n\t// PerlLanguage Perl Language.\n\tPerlLanguage LanguageIdentifier = \"perl\"\n\n\t// Perl6Language Perl Language.\n\tPerl6Language LanguageIdentifier = \"perl6\"\n\n\t// PHPLanguage PHP Language.\n\tPHPLanguage LanguageIdentifier = \"php\"\n\n\t// PowershellLanguage Powershell Language.\n\tPowershellLanguage LanguageIdentifier = \"powershell\"\n\n\t// JadeLanguage Pug Language.\n\tJadeLanguage LanguageIdentifier = \"jade\"\n\n\t// PythonLanguage Python Language.\n\tPythonLanguage LanguageIdentifier = \"python\"\n\n\t// RLanguage R Language.\n\tRLanguage LanguageIdentifier = \"r\"\n\n\t// RazorLanguage Razor(cshtml) Language.\n\tRazorLanguage LanguageIdentifier = \"razor\"\n\n\t// RubyLanguage Ruby Language.\n\tRubyLanguage LanguageIdentifier = \"ruby\"\n\n\t// RustLanguage Rust Language.\n\tRustLanguage LanguageIdentifier = \"rust\"\n\n\t// SCSSLanguage SCSS Languages syntax using curly brackets.\n\tSCSSLanguage LanguageIdentifier = \"scss\"\n\n\t// SASSLanguage SCSS Languages indented syntax.\n\tSASSLanguage LanguageIdentifier = \"sass\"\n\n\t// ScalaLanguage Scala Language.\n\tScalaLanguage LanguageIdentifier = \"scala\"\n\n\t// ShaderlabLanguage ShaderLab Language.\n\tShaderlabLanguage LanguageIdentifier = \"shaderlab\"\n\n\t// ShellscriptLanguage Shell Script (Bash) Language.\n\tShellscriptLanguage LanguageIdentifier = \"shellscript\"\n\n\t// SQLLanguage SQL Language.\n\tSQLLanguage LanguageIdentifier = \"sql\"\n\n\t// SwiftLanguage Swift Language.\n\tSwiftLanguage LanguageIdentifier = \"swift\"\n\n\t// TypeScriptLanguage TypeScript Language.\n\tTypeScriptLanguage LanguageIdentifier = \"typescript\"\n\n\t// TypeScriptReactLanguage TypeScript React Language.\n\tTypeScriptReactLanguage LanguageIdentifier = \"typescriptreact\"\n\n\t// TeXLanguage TeX Language.\n\tTeXLanguage LanguageIdentifier = \"tex\"\n\n\t// VBLanguage Visual Basic Language.\n\tVBLanguage LanguageIdentifier = \"vb\"\n\n\t// XMLLanguage XML Language.\n\tXMLLanguage LanguageIdentifier = \"xml\"\n\n\t// XslLanguage XSL Language.\n\tXslLanguage LanguageIdentifier = \"xsl\"\n\n\t// YamlLanguage YAML Language.\n\tYamlLanguage LanguageIdentifier = \"yaml\"\n)\n\n// languageIdentifierMap map of LanguageIdentifiers.\nvar languageIdentifierMap = map[string]LanguageIdentifier{\n\t\"abap\":            ABAPLanguage,\n\t\"bat\":             BatLanguage,\n\t\"bibtex\":          BibtexLanguage,\n\t\"clojure\":         ClojureLanguage,\n\t\"coffeescript\":    CoffeeScriptLanguage,\n\t\"c\":               CLanguage,\n\t\"cpp\":             CppLanguage,\n\t\"csharp\":          CsharpLanguage,\n\t\"css\":             CSSLanguage,\n\t\"diff\":            DiffLanguage,\n\t\"dart\":            DartLanguage,\n\t\"dockerfile\":      DockerfileLanguage,\n\t\"elixir\":          ElixirLanguage,\n\t\"erlang\":          ErlangLanguage,\n\t\"fsharp\":          FsharpLanguage,\n\t\"git-commit\":      GitCommitLanguage,\n\t\"git-rebase\":      GitRebaseLanguage,\n\t\"go\":              GoLanguage,\n\t\"groovy\":          GroovyLanguage,\n\t\"handlebars\":      HandlebarsLanguage,\n\t\"html\":            HTMLLanguage,\n\t\"ini\":             IniLanguage,\n\t\"java\":            JavaLanguage,\n\t\"javascript\":      JavaScriptLanguage,\n\t\"javascriptreact\": JavaScriptReactLanguage,\n\t\"json\":            JSONLanguage,\n\t\"latex\":           LatexLanguage,\n\t\"less\":            LessLanguage,\n\t\"lua\":             LuaLanguage,\n\t\"makefile\":        MakefileLanguage,\n\t\"markdown\":        MarkdownLanguage,\n\t\"objective-c\":     ObjectiveCLanguage,\n\t\"objective-cpp\":   ObjectiveCppLanguage,\n\t\"perl\":            PerlLanguage,\n\t\"perl6\":           Perl6Language,\n\t\"php\":             PHPLanguage,\n\t\"powershell\":      PowershellLanguage,\n\t\"jade\":            JadeLanguage,\n\t\"python\":          PythonLanguage,\n\t\"r\":               RLanguage,\n\t\"razor\":           RazorLanguage,\n\t\"ruby\":            RubyLanguage,\n\t\"rust\":            RustLanguage,\n\t\"scss\":            SCSSLanguage,\n\t\"sass\":            SASSLanguage,\n\t\"scala\":           ScalaLanguage,\n\t\"shaderlab\":       ShaderlabLanguage,\n\t\"shellscript\":     ShellscriptLanguage,\n\t\"sql\":             SQLLanguage,\n\t\"swift\":           SwiftLanguage,\n\t\"typescript\":      TypeScriptLanguage,\n\t\"typescriptreact\": TypeScriptReactLanguage,\n\t\"tex\":             TeXLanguage,\n\t\"vb\":              VBLanguage,\n\t\"xml\":             XMLLanguage,\n\t\"xsl\":             XslLanguage,\n\t\"yaml\":            YamlLanguage,\n}\n\n// ToLanguageIdentifier converts ft to LanguageIdentifier.\nfunc ToLanguageIdentifier(ft string) LanguageIdentifier {\n\tlangID, ok := languageIdentifierMap[ft]\n\tif ok {\n\t\treturn langID\n\t}\n\n\treturn LanguageIdentifier(ft)\n}\n\n// VersionedTextDocumentIdentifier represents an identifier to denote a specific version of a text document.\n//\n// This information usually flows from the client to the server.\ntype VersionedTextDocumentIdentifier struct {\n\tTextDocumentIdentifier\n\n\t// Version is the version number of this document.\n\t//\n\t// The version number of a document will increase after each change, including\n\t// undo/redo. The number doesn't need to be consecutive.\n\tVersion int32 `json:\"version\"`\n}\n\n// OptionalVersionedTextDocumentIdentifier represents an identifier which optionally denotes a specific version of\n// a text document.\n//\n// This information usually flows from the server to the client.\n//\n// @since 3.16.0.\ntype OptionalVersionedTextDocumentIdentifier struct {\n\tTextDocumentIdentifier\n\n\t// Version is the version number of this document. If an optional versioned text document\n\t// identifier is sent from the server to the client and the file is not\n\t// open in the editor (the server has not received an open notification\n\t// before) the server can send `null` to indicate that the version is\n\t// known and the content on disk is the master (as specified with document\n\t// content ownership).\n\t//\n\t// The version number of a document will increase after each change,\n\t// including undo/redo. The number doesn't need to be consecutive.\n\tVersion *int32 `json:\"version\"` // int32 | null\n}\n\n// TextDocumentPositionParams is a parameter literal used in requests to pass a text document and a position\n// inside that document.\n//\n// It is up to the client to decide how a selection is converted into a position when issuing a request for a text\n// document.\n//\n// The client can for example honor or ignore the selection direction to make LSP request consistent with features\n// implemented internally.\ntype TextDocumentPositionParams struct {\n\t// TextDocument is the text document.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Position is the position inside the text document.\n\tPosition Position `json:\"position\"`\n}\n\n// DocumentFilter is a document filter denotes a document through properties like language, scheme or pattern.\n//\n// An example is a filter that applies to TypeScript files on disk.\ntype DocumentFilter struct {\n\t// Language a language id, like `typescript`.\n\tLanguage string `json:\"language,omitempty\"`\n\n\t// Scheme a URI scheme, like `file` or `untitled`.\n\tScheme string `json:\"scheme,omitempty\"`\n\n\t// Pattern a glob pattern, like `*.{ts,js}`.\n\t//\n\t// Glob patterns can have the following syntax:\n\t//  \"*\"\n\t// \"*\" to match one or more characters in a path segment\n\t//  \"?\"\n\t// \"?\" to match on one character in a path segment\n\t//  \"**\"\n\t// \"**\" to match any number of path segments, including none\n\t//  \"{}\"\n\t// \"{}\" to group conditions (e.g. `**/*.{ts,js}` matches all TypeScript and JavaScript files)\n\t//  \"[]\"\n\t// \"[]\" to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n\t//  \"[!...]\"\n\t// \"[!...]\" to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)\n\tPattern string `json:\"pattern,omitempty\"`\n}\n\n// DocumentSelector is a document selector is the combination of one or more document filters.\ntype DocumentSelector []*DocumentFilter\n\n// MarkupKind 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.\ntype MarkupKind string\n\nconst (\n\t// PlainText is supported as a content format.\n\tPlainText MarkupKind = \"plaintext\"\n\n\t// Markdown is supported as a content format.\n\tMarkdown MarkupKind = \"markdown\"\n)\n\n// MarkupContent a `MarkupContent` literal represents a string value which content is interpreted base on its\n// kind flag.\n//\n// Currently the protocol supports `plaintext` and `markdown` as markup kinds.\n//\n// If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.\n// See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting\n//\n// Here is an example how such a string can be constructed using JavaScript / TypeScript:\n//\n//\tlet markdown: MarkdownContent = {\n//\t kind: MarkupKind.Markdown,\n//\t  value: [\n//\t  \t'# Header',\n//\t  \t'Some text',\n//\t  \t'```typescript',\n//\t  'someCode();',\n//\t  '```'\n//\t  ].join('\\n')\n//\t};\n//\n// NOTE: clients might sanitize the return markdown. A client could decide to\n// remove HTML from the markdown to avoid script execution.\ntype MarkupContent struct {\n\t// Kind is the type of the Markup\n\tKind MarkupKind `json:\"kind\"`\n\n\t// Value is the content itself\n\tValue string `json:\"value\"`\n}\n"
  },
  {
    "path": "lsp/protocol/basic_test.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\nfunc TestPosition(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"line\":25,\"character\":1}`\n\t\twantInvalid = `{\"line\":2,\"character\":0}`\n\t)\n\twantType := Position{\n\t\tLine:      25,\n\t\tCharacter: 1,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Position\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Position\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Position\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRange(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}`\n\t\twantInvalid = `{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}`\n\t)\n\twantType := Range{\n\t\tStart: Position{\n\t\t\tLine:      25,\n\t\t\tCharacter: 1,\n\t\t},\n\t\tEnd: Position{\n\t\t\tLine:      27,\n\t\t\tCharacter: 3,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Range\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Range\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Range\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestLocation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"uri\":\"file:///Users/gopher/go/src/github.com/a-h/templ/lsp/protocol/basic_test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}`\n\t\twantInvalid = `{\"uri\":\"file:///Users/gopher/go/src/github.com/a-h/templ/lsp/protocol/basic_test.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}}`\n\t)\n\twantType := Location{\n\t\tURI: uri.File(\"/Users/gopher/go/src/github.com/a-h/templ/lsp/protocol/basic_test.go\"),\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Location\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Location\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Location\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestLocationLink(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"originSelectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"targetUri\":\"file:///path/to/test.go\",\"targetRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"targetSelectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}`\n\t\twantNil     = `{\"targetUri\":\"file:///path/to/test.go\",\"targetRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"targetSelectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}`\n\t\twantInvalid = `{\"originSelectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"targetUri\":\"file:///path/to/test.go\",\"targetRange\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"targetSelectionRange\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}}`\n\t)\n\twantType := LocationLink{\n\t\tOriginSelectionRange: &Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tTargetURI: uri.File(\"/path/to/test.go\"),\n\t\tTargetRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tTargetSelectionRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine: 25, Character: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNil := LocationLink{\n\t\tTargetURI: uri.File(\"/path/to/test.go\"),\n\t\tTargetRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tTargetSelectionRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine: 25, Character: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          LocationLink\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilOriginSelectionRange\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             LocationLink\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilOriginSelectionRange\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got LocationLink\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeDescription(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"href\":\"file:///path/to/test.go\"}`\n\t\twantInvalid = `{\"href\":\"file:///path/to/invalid.go\"}`\n\t)\n\twantType := CodeDescription{\n\t\tHref: uri.File(\"/path/to/test.go\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeDescription\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeDescription\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeDescription\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCommand(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant             = `{\"title\":\"exec echo\",\"command\":\"echo\",\"arguments\":[\"hello\"]}`\n\t\twantNilArguments = `{\"title\":\"exec echo\",\"command\":\"echo\"}`\n\t\twantInvalid      = `{\"title\":\"exec echo\",\"command\":\"true\",\"arguments\":[\"hello\"]}`\n\t)\n\twantType := Command{\n\t\tTitle:     \"exec echo\",\n\t\tCommand:   \"echo\",\n\t\tArguments: []any{\"hello\"},\n\t}\n\twantTypeNilArguments := Command{\n\t\tTitle:   \"exec echo\",\n\t\tCommand: \"echo\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Command\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilArguments\",\n\t\t\t\tfield:          wantTypeNilArguments,\n\t\t\t\twant:           wantNilArguments,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Command\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilArguments\",\n\t\t\t\tfield:            wantNilArguments,\n\t\t\t\twant:             wantTypeNilArguments,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Command\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestChangeAnnotation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"label\":\"testLabel\",\"needsConfirmation\":true,\"description\":\"testDescription\"}`\n\t\twantNilAll  = `{\"label\":\"testLabel\"}`\n\t\twantInvalid = `{\"label\":\"invalidLabel\",\"needsConfirmation\":false,\"description\":\"invalidDescription\"}`\n\t)\n\twantType := ChangeAnnotation{\n\t\tLabel:             \"testLabel\",\n\t\tNeedsConfirmation: true,\n\t\tDescription:       \"testDescription\",\n\t}\n\twantTypeNilAll := ChangeAnnotation{\n\t\tLabel: \"testLabel\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ChangeAnnotation\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilArguments\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ChangeAnnotation\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilArguments\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ChangeAnnotation\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestAnnotatedTextEdit(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\",\"annotationId\":\"testAnnotationIdentifier\"}`\n\t\twantInvalid = `{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\",\"annotationId\":\"invalidAnnotationIdentifier\"}`\n\t)\n\twantType := AnnotatedTextEdit{\n\t\tTextEdit: TextEdit{\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tNewText: \"foo bar\",\n\t\t},\n\t\tAnnotationID: ChangeAnnotationIdentifier(\"testAnnotationIdentifier\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          AnnotatedTextEdit\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             AnnotatedTextEdit\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got AnnotatedTextEdit\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextEdit(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}`\n\t\twantInvalid = `{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\"}`\n\t)\n\twantType := TextEdit{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tNewText: \"foo bar\",\n\t}\n\twantInvalidType := TextEdit{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      2,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      3,\n\t\t\t\tCharacter: 2,\n\t\t\t},\n\t\t},\n\t\tNewText: \"foo bar\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextEdit\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"Invalid\",\n\t\t\t\tfield: TextEdit{\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t},\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextEdit\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantInvalidType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextEdit\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentEdit(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\"}]}`\n\t)\n\twantType := TextDocumentEdit{\n\t\tTextDocument: OptionalVersionedTextDocumentIdentifier{\n\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\tURI: \"file:///path/to/basic.go\",\n\t\t\t},\n\t\t\tVersion: NewVersion(int32(10)),\n\t\t},\n\t\tEdits: []TextEdit{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNewText: \"foo bar\",\n\t\t\t},\n\t\t},\n\t}\n\twantInvalidType := TextDocumentEdit{\n\t\tTextDocument: OptionalVersionedTextDocumentIdentifier{\n\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\tURI: \"file:///path/to/basic.go\",\n\t\t\t},\n\t\t\tVersion: NewVersion(int32(10)),\n\t\t},\n\t\tEdits: []TextEdit{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      2,\n\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      3,\n\t\t\t\t\t\tCharacter: 2,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNewText: \"foo bar\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentEdit\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentEdit\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantInvalidType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentEdit\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCreateFileOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant                  = `{\"overwrite\":true,\"ignoreIfExists\":true}`\n\t\twantNilIgnoreIfExists = `{\"overwrite\":true}`\n\t\twantNilOverwrite      = `{\"ignoreIfExists\":true}`\n\t\twantValidNilAll       = `{}`\n\t\twantInvalid           = `{\"overwrite\":false,\"ignoreIfExists\":false}`\n\t)\n\twantType := CreateFileOptions{\n\t\tOverwrite:      true,\n\t\tIgnoreIfExists: true,\n\t}\n\twantTypeNilOverwrite := CreateFileOptions{\n\t\tIgnoreIfExists: true,\n\t}\n\twantTypeNilIgnoreIfExists := CreateFileOptions{\n\t\tOverwrite: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CreateFileOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilOverwrite\",\n\t\t\t\tfield:          wantTypeNilIgnoreIfExists,\n\t\t\t\twant:           wantNilIgnoreIfExists,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilIgnoreIfExists\",\n\t\t\t\tfield:          wantTypeNilOverwrite,\n\t\t\t\twant:           wantNilOverwrite,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          CreateFileOptions{},\n\t\t\t\twant:           wantValidNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CreateFileOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:  \"Valid\",\n\t\t\t\tfield: `{\"overwrite\":true,\"ignoreIfExists\":true}`,\n\t\t\t\twant: CreateFileOptions{\n\t\t\t\t\tOverwrite:      true,\n\t\t\t\t\tIgnoreIfExists: true,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:  \"ValidNilOverwrite\",\n\t\t\t\tfield: `{\"ignoreIfExists\":true}`,\n\t\t\t\twant: CreateFileOptions{\n\t\t\t\t\tIgnoreIfExists: true,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:  \"ValidNilIgnoreIfExists\",\n\t\t\t\tfield: `{\"overwrite\":true}`,\n\t\t\t\twant: CreateFileOptions{\n\t\t\t\t\tOverwrite: true,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            `{}`,\n\t\t\t\twant:             CreateFileOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:  \"Invalid\",\n\t\t\t\tfield: `{\"overwrite\":true,\"ignoreIfExists\":true}`,\n\t\t\t\twant: CreateFileOptions{\n\t\t\t\t\tOverwrite:      false,\n\t\t\t\t\tIgnoreIfExists: false,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CreateFileOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCreateFile(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant           = `{\"kind\":\"create\",\"uri\":\"file:///path/to/basic.go\",\"options\":{\"overwrite\":true,\"ignoreIfExists\":true},\"annotationId\":\"testAnnotationIdentifier\"}`\n\t\twantNilOptions = `{\"kind\":\"create\",\"uri\":\"file:///path/to/basic.go\"}`\n\t\twantInvalid    = `{\"kind\":\"create\",\"uri\":\"file:///path/to/basic_gen.go\",\"options\":{\"overwrite\":false,\"ignoreIfExists\":false},\"annotationId\":\"invalidAnnotationIdentifier\"}`\n\t)\n\twantType := CreateFile{\n\t\tKind: \"create\",\n\t\tURI:  uri.File(\"/path/to/basic.go\"),\n\t\tOptions: &CreateFileOptions{\n\t\t\tOverwrite:      true,\n\t\t\tIgnoreIfExists: true,\n\t\t},\n\t\tAnnotationID: ChangeAnnotationIdentifier(\"testAnnotationIdentifier\"),\n\t}\n\twantTypeNilOptions := CreateFile{\n\t\tKind: \"create\",\n\t\tURI:  uri.File(\"/path/to/basic.go\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CreateFile\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilOptions\",\n\t\t\t\tfield:          wantTypeNilOptions,\n\t\t\t\twant:           wantNilOptions,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CreateFile\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilOptions\",\n\t\t\t\tfield:            wantNilOptions,\n\t\t\t\twant:             wantTypeNilOptions,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CreateFile\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRenameFileOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant                  = `{\"overwrite\":true,\"ignoreIfExists\":true}`\n\t\twantNilOverwrite      = `{\"ignoreIfExists\":true}`\n\t\twantNilIgnoreIfExists = `{\"overwrite\":true}`\n\t\twantNilAll            = `{}`\n\t\twantInvalid           = `{\"overwrite\":false,\"ignoreIfExists\":false}`\n\t)\n\twantType := RenameFileOptions{\n\t\tOverwrite:      true,\n\t\tIgnoreIfExists: true,\n\t}\n\twantTypeNilOverwrite := RenameFileOptions{\n\t\tIgnoreIfExists: true,\n\t}\n\twantTypeNilIgnoreIfExists := RenameFileOptions{\n\t\tOverwrite: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RenameFileOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilOverwrite\",\n\t\t\t\tfield:          wantTypeNilOverwrite,\n\t\t\t\twant:           wantNilOverwrite,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilIgnoreIfExists\",\n\t\t\t\tfield:          wantTypeNilIgnoreIfExists,\n\t\t\t\twant:           wantNilIgnoreIfExists,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          RenameFileOptions{},\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RenameFileOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:  \"Valid\",\n\t\t\t\tfield: `{\"overwrite\":true,\"ignoreIfExists\":true}`,\n\t\t\t\twant: RenameFileOptions{\n\t\t\t\t\tOverwrite:      true,\n\t\t\t\t\tIgnoreIfExists: true,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:  \"ValidNilOverwrite\",\n\t\t\t\tfield: `{\"ignoreIfExists\":true}`,\n\t\t\t\twant: RenameFileOptions{\n\t\t\t\t\tIgnoreIfExists: true,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:  \"ValidNilIgnoreIfExists\",\n\t\t\t\tfield: `{\"overwrite\":true}`,\n\t\t\t\twant: RenameFileOptions{\n\t\t\t\t\tOverwrite: true,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            `{}`,\n\t\t\t\twant:             RenameFileOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:  \"Invalid\",\n\t\t\t\tfield: `{\"overwrite\":true,\"ignoreIfExists\":true}`,\n\t\t\t\twant: RenameFileOptions{\n\t\t\t\t\tOverwrite:      false,\n\t\t\t\t\tIgnoreIfExists: false,\n\t\t\t\t},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RenameFileOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRenameFile(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant           = `{\"kind\":\"rename\",\"oldUri\":\"file:///path/to/old.go\",\"newUri\":\"file:///path/to/new.go\",\"options\":{\"overwrite\":true,\"ignoreIfExists\":true},\"annotationId\":\"testAnnotationIdentifier\"}`\n\t\twantNilOptions = `{\"kind\":\"rename\",\"oldUri\":\"file:///path/to/old.go\",\"newUri\":\"file:///path/to/new.go\"}`\n\t\twantInvalid    = `{\"kind\":\"rename\",\"oldUri\":\"file:///path/to/old2.go\",\"newUri\":\"file:///path/to/new2.go\",\"options\":{\"overwrite\":false,\"ignoreIfExists\":false},\"annotationId\":\"invalidAnnotationIdentifier\"}`\n\t)\n\twantType := RenameFile{\n\t\tKind:   \"rename\",\n\t\tOldURI: uri.File(\"/path/to/old.go\"),\n\t\tNewURI: uri.File(\"/path/to/new.go\"),\n\t\tOptions: &RenameFileOptions{\n\t\t\tOverwrite:      true,\n\t\t\tIgnoreIfExists: true,\n\t\t},\n\t\tAnnotationID: ChangeAnnotationIdentifier(\"testAnnotationIdentifier\"),\n\t}\n\twantTypeNilOptions := RenameFile{\n\t\tKind:   \"rename\",\n\t\tOldURI: uri.File(\"/path/to/old.go\"),\n\t\tNewURI: uri.File(\"/path/to/new.go\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RenameFile\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilOptions\",\n\t\t\t\tfield:          wantTypeNilOptions,\n\t\t\t\twant:           wantNilOptions,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RenameFile\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilOptions\",\n\t\t\t\tfield:            wantNilOptions,\n\t\t\t\twant:             wantTypeNilOptions,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RenameFile\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDeleteFileOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant                    = `{\"recursive\":true,\"ignoreIfNotExists\":true}`\n\t\twantNilRecursive        = `{\"ignoreIfNotExists\":true}`\n\t\twantNiIgnoreIfNotExists = `{\"recursive\":true}`\n\t\twantNilAll              = `{}`\n\t\twantInvalid             = `{\"recursive\":false,\"ignoreIfNotExists\":false}`\n\t)\n\twantType := DeleteFileOptions{\n\t\tRecursive:         true,\n\t\tIgnoreIfNotExists: true,\n\t}\n\twantTypeNilRecursive := DeleteFileOptions{\n\t\tIgnoreIfNotExists: true,\n\t}\n\twantTypeNiIgnoreIfNotExists := DeleteFileOptions{\n\t\tRecursive: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DeleteFileOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilRecursive\",\n\t\t\t\tfield:          wantTypeNilRecursive,\n\t\t\t\twant:           wantNilRecursive,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNiIgnoreIfNotExists\",\n\t\t\t\tfield:          wantTypeNiIgnoreIfNotExists,\n\t\t\t\twant:           wantNiIgnoreIfNotExists,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DeleteFileOptions{},\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DeleteFileOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilRecursive\",\n\t\t\t\tfield:            wantNilRecursive,\n\t\t\t\twant:             wantTypeNilRecursive,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilIgnoreIfNotExists\",\n\t\t\t\tfield:            wantNiIgnoreIfNotExists,\n\t\t\t\twant:             wantTypeNiIgnoreIfNotExists,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             DeleteFileOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DeleteFileOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDeleteFile(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant           = `{\"kind\":\"delete\",\"uri\":\"file:///path/to/delete.go\",\"options\":{\"recursive\":true,\"ignoreIfNotExists\":true},\"annotationId\":\"testAnnotationIdentifier\"}`\n\t\twantNilOptions = `{\"kind\":\"delete\",\"uri\":\"file:///path/to/delete.go\"}`\n\t\twantInvalid    = `{\"kind\":\"delete\",\"uri\":\"file:///path/to/delete2.go\",\"options\":{\"recursive\":false,\"ignoreIfNotExists\":false},\"annotationId\":\"invalidAnnotationIdentifier\"}`\n\t)\n\twantType := DeleteFile{\n\t\tKind: \"delete\",\n\t\tURI:  uri.File(\"/path/to/delete.go\"),\n\t\tOptions: &DeleteFileOptions{\n\t\t\tRecursive:         true,\n\t\t\tIgnoreIfNotExists: true,\n\t\t},\n\t\tAnnotationID: ChangeAnnotationIdentifier(\"testAnnotationIdentifier\"),\n\t}\n\twantTypeNilOptions := DeleteFile{\n\t\tKind: \"delete\",\n\t\tURI:  uri.File(\"/path/to/delete.go\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DeleteFile\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilOptions\",\n\t\t\t\tfield:          wantTypeNilOptions,\n\t\t\t\twant:           wantNilOptions,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DeleteFile\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilOptions\",\n\t\t\t\tfield:            wantNilOptions,\n\t\t\t\twant:             wantTypeNilOptions,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DeleteFile\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkspaceEdit(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant                   = `{\"changes\":{\"file:///path/to/basic.go\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]},\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}],\"changeAnnotations\":{\"testAnnotationIdentifier\":{\"label\":\"testLabel\",\"needsConfirmation\":true,\"description\":\"testDescription\"}}}`\n\t\twantNilChanges         = `{\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}]}`\n\t\twantNilDocumentChanges = `{\"changes\":{\"file:///path/to/basic.go\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}}`\n\t\twantInvalid            = `{\"changes\":{\"file:///path/to/basic_gen.go\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\"}]},\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\"}]}]}`\n\t)\n\twantType := WorkspaceEdit{\n\t\tChanges: map[uri.URI][]TextEdit{\n\t\t\turi.File(\"/path/to/basic.go\"): {\n\t\t\t\t{\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tDocumentChanges: []TextDocumentEdit{\n\t\t\t{\n\t\t\t\tTextDocument: OptionalVersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t\t\t},\n\t\t\t\t\tVersion: NewVersion(int32(10)),\n\t\t\t\t},\n\t\t\t\tEdits: []TextEdit{\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tChangeAnnotations: map[ChangeAnnotationIdentifier]ChangeAnnotation{\n\t\t\tChangeAnnotationIdentifier(\"testAnnotationIdentifier\"): {\n\t\t\t\tLabel:             \"testLabel\",\n\t\t\t\tNeedsConfirmation: true,\n\t\t\t\tDescription:       \"testDescription\",\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilChanges := WorkspaceEdit{\n\t\tDocumentChanges: []TextDocumentEdit{\n\t\t\t{\n\t\t\t\tTextDocument: OptionalVersionedTextDocumentIdentifier{\n\t\t\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t\t\t},\n\t\t\t\t\tVersion: NewVersion(int32(10)),\n\t\t\t\t},\n\t\t\t\tEdits: []TextEdit{\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilDocumentChanges := WorkspaceEdit{\n\t\tChanges: map[uri.URI][]TextEdit{\n\t\t\turi.File(\"/path/to/basic.go\"): {\n\t\t\t\t{\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceEdit\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilChanges\",\n\t\t\t\tfield:          wantTypeNilChanges,\n\t\t\t\twant:           wantNilChanges,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilDocumentChanges\",\n\t\t\t\tfield:          wantTypeNilDocumentChanges,\n\t\t\t\twant:           wantNilDocumentChanges,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceEdit\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilChanges\",\n\t\t\t\tfield:            wantNilChanges,\n\t\t\t\twant:             wantTypeNilChanges,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilDocumentChanges\",\n\t\t\t\tfield:            wantNilDocumentChanges,\n\t\t\t\twant:             wantTypeNilDocumentChanges,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceEdit\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentIdentifier(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant             = `{\"uri\":\"file:///path/to/basic.go\"}`\n\t\twantInvalid      = `{\"uri\":\"file:///path/to/unknown.go\"}`\n\t\twantInvalidEmpty = `{}`\n\t)\n\twantType := TextDocumentIdentifier{\n\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentIdentifier\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"InvalidEmpty\",\n\t\t\t\tfield:          TextDocumentIdentifier{},\n\t\t\t\twant:           wantInvalidEmpty,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentIdentifier\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentIdentifier\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentItem(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"uri\":\"file:///path/to/basic.go\",\"languageId\":\"go\",\"version\":10,\"text\":\"Go Language\"}`\n\t\twantInvalid = `{\"uri\":\"file:///path/to/basic_gen.go\",\"languageId\":\"cpp\",\"version\":10,\"text\":\"C++ Language\"}`\n\t)\n\twantType := TextDocumentItem{\n\t\tURI:        uri.File(\"/path/to/basic.go\"),\n\t\tLanguageID: GoLanguage,\n\t\tVersion:    int32(10),\n\t\tText:       \"Go Language\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentItem\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentItem\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentItem\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestToLanguageIdentifier(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tft   string\n\t\twant LanguageIdentifier\n\t}{\n\t\t{\n\t\t\tname: \"Go\",\n\t\t\tft:   \"go\",\n\t\t\twant: GoLanguage,\n\t\t},\n\t\t{\n\t\t\tname: \"C\",\n\t\t\tft:   \"c\",\n\t\t\twant: CLanguage,\n\t\t},\n\t\t{\n\t\t\tname: \"lsif\",\n\t\t\tft:   \"lsif\",\n\t\t\twant: LanguageIdentifier(\"lsif\"),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := ToLanguageIdentifier(tt.ft); got != tt.want {\n\t\t\t\tt.Errorf(\"ToLanguageIdentifier(%v) = %v, want %v\", tt.ft, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestVersionedTextDocumentIdentifier(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant            = `{\"uri\":\"file:///path/to/basic.go\",\"version\":10}`\n\t\twantZeroVersion = `{\"uri\":\"file:///path/to/basic.go\",\"version\":0}`\n\t\twantInvalid     = `{\"uri\":\"file:///path/to/basic_gen.go\",\"version\":50}`\n\t)\n\twantType := VersionedTextDocumentIdentifier{\n\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t},\n\t\tVersion: int32(10),\n\t}\n\twantTypeNullVersion := VersionedTextDocumentIdentifier{\n\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          VersionedTextDocumentIdentifier\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNullVersion\",\n\t\t\t\tfield:          wantTypeNullVersion,\n\t\t\t\twant:           wantZeroVersion,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             VersionedTextDocumentIdentifier\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNullVersion\",\n\t\t\t\tfield:            wantZeroVersion,\n\t\t\t\twant:             wantTypeNullVersion,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got VersionedTextDocumentIdentifier\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestOptionalVersionedTextDocumentIdentifier(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant            = `{\"uri\":\"file:///path/to/basic.go\",\"version\":10}`\n\t\twantNullVersion = `{\"uri\":\"file:///path/to/basic.go\",\"version\":null}`\n\t\twantInvalid     = `{\"uri\":\"file:///path/to/basic_gen.go\",\"version\":50}`\n\t)\n\twantType := OptionalVersionedTextDocumentIdentifier{\n\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t},\n\t\tVersion: NewVersion(10),\n\t}\n\twantTypeNullVersion := OptionalVersionedTextDocumentIdentifier{\n\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          OptionalVersionedTextDocumentIdentifier\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNullVersion\",\n\t\t\t\tfield:          wantTypeNullVersion,\n\t\t\t\twant:           wantNullVersion,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             OptionalVersionedTextDocumentIdentifier\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNullVersion\",\n\t\t\t\tfield:            wantNullVersion,\n\t\t\t\twant:             wantTypeNullVersion,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got OptionalVersionedTextDocumentIdentifier\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentPositionParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1}}`\n\t)\n\twantType := TextDocumentPositionParams{\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t},\n\t\tPosition: Position{\n\t\t\tLine:      25,\n\t\t\tCharacter: 1,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentPositionParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentPositionParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentPositionParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentFilter(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant            = `{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}`\n\t\twantNilLanguage = `{\"scheme\":\"file\",\"pattern\":\"*\"}`\n\t\twantNilScheme   = `{\"language\":\"go\",\"pattern\":\"*\"}`\n\t\twantNilPattern  = `{\"language\":\"go\",\"scheme\":\"file\"}`\n\t\twantNilAll      = `{}`\n\t\twantInvalid     = `{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"?\"}`\n\t)\n\twantType := DocumentFilter{\n\t\tLanguage: \"go\",\n\t\tScheme:   \"file\",\n\t\tPattern:  \"*\",\n\t}\n\twantTypeNilLanguage := DocumentFilter{\n\t\tScheme:  \"file\",\n\t\tPattern: \"*\",\n\t}\n\twantTypeNilScheme := DocumentFilter{\n\t\tLanguage: \"go\",\n\t\tPattern:  \"*\",\n\t}\n\twantTypeNilPattern := DocumentFilter{\n\t\tLanguage: \"go\",\n\t\tScheme:   \"file\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentFilter\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilLanguage\",\n\t\t\t\tfield:          wantTypeNilLanguage,\n\t\t\t\twant:           wantNilLanguage,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilScheme\",\n\t\t\t\tfield:          wantTypeNilScheme,\n\t\t\t\twant:           wantNilScheme,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilPattern\",\n\t\t\t\tfield:          wantTypeNilPattern,\n\t\t\t\twant:           wantNilPattern,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentFilter{},\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentFilter\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilLanguage\",\n\t\t\t\tfield:            wantNilLanguage,\n\t\t\t\twant:             wantTypeNilLanguage,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilScheme\",\n\t\t\t\tfield:            wantNilScheme,\n\t\t\t\twant:             wantTypeNilScheme,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilPattern\",\n\t\t\t\tfield:            wantNilPattern,\n\t\t\t\twant:             wantTypeNilPattern,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             DocumentFilter{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentFilter\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentSelector(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}]`\n\t\twantInvalid = `[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"},{\"language\":\"c\",\"scheme\":\"untitled\",\"pattern\":\"*.{c,h}\"}]`\n\t)\n\twantType := DocumentSelector{\n\t\t{\n\t\t\tLanguage: \"go\",\n\t\t\tScheme:   \"file\",\n\t\t\tPattern:  \"*.go\",\n\t\t},\n\t\t{\n\t\t\tLanguage: \"cpp\",\n\t\t\tScheme:   \"untitled\",\n\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentSelector\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentSelector\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentSelector\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestMarkupContent(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = \"{\\\"kind\\\":\\\"markdown\\\",\\\"value\\\":\\\"# Header\\\\nSome text\\\\n```typescript\\\\nsomeCode();\\\\n'```\\\\n\\\"}\"\n\t\twantInvalid = \"{\\\"kind\\\":\\\"plaintext\\\",\\\"value\\\":\\\"Header\\\\nSome text\\\\ntypescript\\\\nsomeCode();\\\\n\\\"}\"\n\t)\n\twantType := MarkupContent{\n\t\tKind:  Markdown,\n\t\tValue: \"# Header\\nSome text\\n```typescript\\nsomeCode();\\n'```\\n\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          MarkupContent\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             MarkupContent\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got MarkupContent\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/callhierarchy.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// CallHierarchy capabilities specific to the \"textDocument/callHierarchy\".\n//\n// @since 3.16.0.\ntype CallHierarchy struct {\n\t// DynamicRegistration whether implementation supports dynamic registration.\n\t//\n\t// If this is set to \"true\" the client supports the new\n\t// TextDocumentRegistrationOptions && StaticRegistrationOptions return\n\t// value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// CallHierarchyPrepareParams params of CallHierarchyPrepare.\n//\n// @since 3.16.0.\ntype CallHierarchyPrepareParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n}\n\n// CallHierarchyItem is the result of a \"textDocument/prepareCallHierarchy\" request.\n//\n// @since 3.16.0.\ntype CallHierarchyItem struct {\n\t// name is the name of this item.\n\tName string `json:\"name\"`\n\n\t// Kind is the kind of this item.\n\tKind SymbolKind `json:\"kind\"`\n\n\t// Tags for this item.\n\tTags []SymbolTag `json:\"tags,omitempty\"`\n\n\t// Detail more detail for this item, e.g. the signature of a function.\n\tDetail string `json:\"detail,omitempty\"`\n\n\t// URI is the resource identifier of this item.\n\tURI DocumentURI `json:\"uri\"`\n\n\t// Range is the range enclosing this symbol not including leading/trailing whitespace\n\t// but everything else, e.g. comments and code.\n\tRange Range `json:\"range\"`\n\n\t// SelectionRange is the range that should be selected and revealed when this symbol is being\n\t// picked, e.g. the name of a function. Must be contained by the\n\t// Range.\n\tSelectionRange Range `json:\"selectionRange\"`\n\n\t// Data is a data entry field that is preserved between a call hierarchy prepare and\n\t// incoming calls or outgoing calls requests.\n\tData any `json:\"data,omitempty\"`\n}\n\n// CallHierarchyIncomingCallsParams params of CallHierarchyIncomingCalls.\n//\n// @since 3.16.0.\ntype CallHierarchyIncomingCallsParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// Item is the IncomingCalls item.\n\tItem CallHierarchyItem `json:\"item\"`\n}\n\n// CallHierarchyIncomingCall is the result of a \"callHierarchy/incomingCalls\" request.\n//\n// @since 3.16.0.\ntype CallHierarchyIncomingCall struct {\n\t// From is the item that makes the call.\n\tFrom CallHierarchyItem `json:\"from\"`\n\n\t// FromRanges is the ranges at which the calls appear. This is relative to the caller\n\t// denoted by From.\n\tFromRanges []Range `json:\"fromRanges\"`\n}\n\n// CallHierarchyOutgoingCallsParams params of CallHierarchyOutgoingCalls.\n//\n// @since 3.16.0.\ntype CallHierarchyOutgoingCallsParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// Item is the OutgoingCalls item.\n\tItem CallHierarchyItem `json:\"item\"`\n}\n\n// CallHierarchyOutgoingCall is the result of a \"callHierarchy/outgoingCalls\" request.\n//\n// @since 3.16.0.\ntype CallHierarchyOutgoingCall struct {\n\t// To is the item that is called.\n\tTo CallHierarchyItem `json:\"to\"`\n\n\t// FromRanges is the range at which this item is called. This is the range relative to\n\t// the caller, e.g the item passed to \"callHierarchy/outgoingCalls\" request.\n\tFromRanges []Range `json:\"fromRanges\"`\n}\n"
  },
  {
    "path": "lsp/protocol/callhierarchy_test.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\nfunc TestCallHierarchy(t *testing.T) {\n\tconst (\n\t\twant        = `{\"dynamicRegistration\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"dynamicRegistration\":false}`\n\t)\n\twantType := CallHierarchy{\n\t\tDynamicRegistration: true,\n\t}\n\twantTypeNil := CallHierarchy{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchy\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchy\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchy\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyOptions(t *testing.T) {\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := CallHierarchyOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\twantTypeNil := CallHierarchyOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyRegistrationOptions(t *testing.T) {\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"}],\"workDoneProgress\":true,\"id\":\"testID\"}`\n\t\twantNil     = `{\"documentSelector\":[]}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := CallHierarchyRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tCallHierarchyOptions: CallHierarchyOptions{\n\t\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\t\tWorkDoneProgress: true,\n\t\t\t},\n\t\t},\n\t\tStaticRegistrationOptions: StaticRegistrationOptions{\n\t\t\tID: \"testID\",\n\t\t},\n\t}\n\twantTypeNil := CallHierarchyRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyPrepareParams(t *testing.T) {\n\tconst (\n\t\twantWorkDoneToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidWorkDoneToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\"}`\n\t\twantNil     = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + invalidWorkDoneToken + `\"}`\n\t)\n\twantType := CallHierarchyPrepareParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t}\n\twantTypeNil := CallHierarchyPrepareParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyPrepareParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyPrepareParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyPrepareParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyItem(t *testing.T) {\n\tconst (\n\t\twant        = `{\"name\":\"testName\",\"kind\":1,\"tags\":[1],\"detail\":\"testDetail\",\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"data\":\"testData\"}`\n\t\twantNil     = `{\"name\":\"testName\",\"kind\":1,\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}`\n\t\twantInvalid = `{\"name\":\"invalidName\",\"kind\":0,\"tags\":[0],\"detail\":\"invalidDetail\",\"uri\":\"file:///path/to/invalid.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"selectionRange\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"data\":\"invalidData\"}`\n\t)\n\twantType := CallHierarchyItem{\n\t\tName: \"testName\",\n\t\tKind: SymbolKindFile,\n\t\tTags: []SymbolTag{\n\t\t\tSymbolTagDeprecated,\n\t\t},\n\t\tDetail: \"testDetail\",\n\t\tURI:    uri.File(\"/path/to/basic.go\"),\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tSelectionRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tData: \"testData\",\n\t}\n\twantTypeNil := CallHierarchyItem{\n\t\tName: \"testName\",\n\t\tKind: SymbolKindFile,\n\t\tURI:  uri.File(\"/path/to/basic.go\"),\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tSelectionRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyItem\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyItem\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyItem\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyIncomingCallsParams(t *testing.T) {\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"item\":{\"name\":\"testName\",\"kind\":1,\"tags\":[1],\"detail\":\"testDetail\",\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"data\":\"testData\"}}`\n\t\twantNil     = `{\"item\":{\"name\":\"testName\",\"kind\":1,\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"item\":{\"name\":\"invalidName\",\"kind\":0,\"tags\":[0],\"detail\":\"invalidDetail\",\"uri\":\"file:///path/to/invalid.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"selectionRange\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"data\":\"invalidData\"}}`\n\t)\n\twantType := CallHierarchyIncomingCallsParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tItem: CallHierarchyItem{\n\t\t\tName: \"testName\",\n\t\t\tKind: SymbolKindFile,\n\t\t\tTags: []SymbolTag{\n\t\t\t\tSymbolTagDeprecated,\n\t\t\t},\n\t\t\tDetail: \"testDetail\",\n\t\t\tURI:    uri.File(\"/path/to/basic.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSelectionRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tData: \"testData\",\n\t\t},\n\t}\n\twantTypeNil := CallHierarchyIncomingCallsParams{\n\t\tItem: CallHierarchyItem{\n\t\t\tName: \"testName\",\n\t\t\tKind: SymbolKindFile,\n\t\t\tURI:  uri.File(\"/path/to/basic.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSelectionRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyIncomingCallsParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyIncomingCallsParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyIncomingCallsParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyIncomingCall(t *testing.T) {\n\tconst (\n\t\twant        = `{\"from\":{\"name\":\"testName\",\"kind\":1,\"tags\":[1],\"detail\":\"testDetail\",\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"data\":\"testData\"},\"fromRanges\":[{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}]}`\n\t\twantInvalid = `{\"from\":{\"name\":\"invalidName\",\"kind\":0,\"tags\":[0],\"detail\":\"invalidDetail\",\"uri\":\"file:///path/to/invalid.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"selectionRange\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"data\":\"invalidData\"},\"fromRanges\":[{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}]}`\n\t)\n\twantType := CallHierarchyIncomingCall{\n\t\tFrom: CallHierarchyItem{\n\t\t\tName: \"testName\",\n\t\t\tKind: SymbolKindFile,\n\t\t\tTags: []SymbolTag{\n\t\t\t\tSymbolTagDeprecated,\n\t\t\t},\n\t\t\tDetail: \"testDetail\",\n\t\t\tURI:    uri.File(\"/path/to/basic.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSelectionRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tData: \"testData\",\n\t\t},\n\t\tFromRanges: []Range{\n\t\t\t{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyIncomingCall\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyIncomingCall\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyIncomingCall\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyOutgoingCallsParams(t *testing.T) {\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"item\":{\"name\":\"testName\",\"kind\":1,\"tags\":[1],\"detail\":\"testDetail\",\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"data\":\"testData\"}}`\n\t\twantNil     = `{\"item\":{\"name\":\"testName\",\"kind\":1,\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"item\":{\"name\":\"invalidName\",\"kind\":0,\"tags\":[0],\"detail\":\"invalidDetail\",\"uri\":\"file:///path/to/invalid.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"selectionRange\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"data\":\"invalidData\"}}`\n\t)\n\twantType := CallHierarchyOutgoingCallsParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tItem: CallHierarchyItem{\n\t\t\tName: \"testName\",\n\t\t\tKind: SymbolKindFile,\n\t\t\tTags: []SymbolTag{\n\t\t\t\tSymbolTagDeprecated,\n\t\t\t},\n\t\t\tDetail: \"testDetail\",\n\t\t\tURI:    uri.File(\"/path/to/basic.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSelectionRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tData: \"testData\",\n\t\t},\n\t}\n\twantTypeNil := CallHierarchyOutgoingCallsParams{\n\t\tItem: CallHierarchyItem{\n\t\t\tName: \"testName\",\n\t\t\tKind: SymbolKindFile,\n\t\t\tURI:  uri.File(\"/path/to/basic.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSelectionRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyOutgoingCallsParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyOutgoingCallsParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyOutgoingCallsParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCallHierarchyOutgoingCall(t *testing.T) {\n\tconst (\n\t\twant        = `{\"to\":{\"name\":\"testName\",\"kind\":1,\"tags\":[1],\"detail\":\"testDetail\",\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"data\":\"testData\"},\"fromRanges\":[{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}]}`\n\t\twantInvalid = `{\"to\":{\"name\":\"invalidName\",\"kind\":0,\"tags\":[0],\"detail\":\"invalidDetail\",\"uri\":\"file:///path/to/invalid.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"selectionRange\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"data\":\"invalidData\"},\"fromRanges\":[{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}]}`\n\t)\n\twantType := CallHierarchyOutgoingCall{\n\t\tTo: CallHierarchyItem{\n\t\t\tName: \"testName\",\n\t\t\tKind: SymbolKindFile,\n\t\t\tTags: []SymbolTag{\n\t\t\t\tSymbolTagDeprecated,\n\t\t\t},\n\t\t\tDetail: \"testDetail\",\n\t\t\tURI:    uri.File(\"/path/to/basic.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSelectionRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tData: \"testData\",\n\t\t},\n\t\tFromRanges: []Range{\n\t\t\t{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CallHierarchyOutgoingCall\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CallHierarchyOutgoingCall\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CallHierarchyOutgoingCall\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/capabilities_client.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport \"strconv\"\n\n// ClientCapabilities now define capabilities for dynamic registration, workspace and text document features\n// the client supports.\n//\n// The experimental can be used to pass experimental capabilities under development.\n//\n// For future compatibility a ClientCapabilities object literal can have more properties set than currently defined.\n// Servers receiving a ClientCapabilities object literal with unknown properties should ignore these properties.\n//\n// A missing property should be interpreted as an absence of the capability.\n// If a missing property normally defines sub properties, all missing sub properties should be interpreted\n// as an absence of the corresponding capability.\ntype ClientCapabilities struct {\n\t// Workspace specific client capabilities.\n\tWorkspace *WorkspaceClientCapabilities `json:\"workspace,omitempty\"`\n\n\t// TextDocument specific client capabilities.\n\tTextDocument *TextDocumentClientCapabilities `json:\"textDocument,omitempty\"`\n\n\t// Window specific client capabilities.\n\tWindow *WindowClientCapabilities `json:\"window,omitempty\"`\n\n\t// General client capabilities.\n\t//\n\t// @since 3.16.0.\n\tGeneral *GeneralClientCapabilities `json:\"general,omitempty\"`\n\n\t// Experimental client capabilities.\n\tExperimental any `json:\"experimental,omitempty\"`\n}\n\n// WorkspaceClientCapabilities Workspace specific client capabilities.\ntype WorkspaceClientCapabilities struct {\n\t// The client supports applying batch edits to the workspace by supporting\n\t// the request \"workspace/applyEdit\".\n\tApplyEdit bool `json:\"applyEdit,omitempty\"`\n\n\t// WorkspaceEdit capabilities specific to `WorkspaceEdit`s.\n\tWorkspaceEdit *WorkspaceClientCapabilitiesWorkspaceEdit `json:\"workspaceEdit,omitempty\"`\n\n\t// DidChangeConfiguration capabilities specific to the `workspace/didChangeConfiguration` notification.\n\tDidChangeConfiguration *DidChangeConfigurationWorkspaceClientCapabilities `json:\"didChangeConfiguration,omitempty\"`\n\n\t// DidChangeWatchedFiles capabilities specific to the `workspace/didChangeWatchedFiles` notification.\n\tDidChangeWatchedFiles *DidChangeWatchedFilesWorkspaceClientCapabilities `json:\"didChangeWatchedFiles,omitempty\"`\n\n\t// Symbol capabilities specific to the \"workspace/symbol\" request.\n\tSymbol *WorkspaceSymbolClientCapabilities `json:\"symbol,omitempty\"`\n\n\t// ExecuteCommand capabilities specific to the \"workspace/executeCommand\" request.\n\tExecuteCommand *ExecuteCommandClientCapabilities `json:\"executeCommand,omitempty\"`\n\n\t// WorkspaceFolders is the client has support for workspace folders.\n\t//\n\t// @since 3.6.0.\n\tWorkspaceFolders bool `json:\"workspaceFolders,omitempty\"`\n\n\t// Configuration is the client supports \"workspace/configuration\" requests.\n\t//\n\t// @since 3.6.0.\n\tConfiguration bool `json:\"configuration,omitempty\"`\n\n\t// SemanticTokens is the capabilities specific to the semantic token requests scoped to the\n\t// workspace.\n\t//\n\t// @since 3.16.0.\n\tSemanticTokens *SemanticTokensWorkspaceClientCapabilities `json:\"semanticTokens,omitempty\"`\n\n\t// CodeLens is the Capabilities specific to the code lens requests scoped to the\n\t// workspace.\n\t//\n\t// @since 3.16.0.\n\tCodeLens *CodeLensWorkspaceClientCapabilities `json:\"codeLens,omitempty\"`\n\n\t// FileOperations is the client has support for file requests/notifications.\n\t//\n\t// @since 3.16.0.\n\tFileOperations *WorkspaceClientCapabilitiesFileOperations `json:\"fileOperations,omitempty\"`\n}\n\n// WorkspaceClientCapabilitiesWorkspaceEdit capabilities specific to \"WorkspaceEdit\"s.\ntype WorkspaceClientCapabilitiesWorkspaceEdit struct {\n\t// DocumentChanges is the client supports versioned document changes in `WorkspaceEdit`s\n\tDocumentChanges bool `json:\"documentChanges,omitempty\"`\n\n\t// FailureHandling is the failure handling strategy of a client if applying the workspace edit\n\t// fails.\n\t//\n\t// Mostly FailureHandlingKind.\n\tFailureHandling string `json:\"failureHandling,omitempty\"`\n\n\t// ResourceOperations is the resource operations the client supports. Clients should at least\n\t// support \"create\", \"rename\" and \"delete\" files and folders.\n\tResourceOperations []string `json:\"resourceOperations,omitempty\"`\n\n\t// NormalizesLineEndings whether the client normalizes line endings to the client specific\n\t// setting.\n\t// If set to `true` the client will normalize line ending characters\n\t// in a workspace edit to the client specific new line character(s).\n\t//\n\t// @since 3.16.0.\n\tNormalizesLineEndings bool `json:\"normalizesLineEndings,omitempty\"`\n\n\t// ChangeAnnotationSupport whether the client in general supports change annotations on text edits,\n\t// create file, rename file and delete file changes.\n\t//\n\t// @since 3.16.0.\n\tChangeAnnotationSupport *WorkspaceClientCapabilitiesWorkspaceEditChangeAnnotationSupport `json:\"changeAnnotationSupport,omitempty\"`\n}\n\n// FailureHandlingKind is the kind of failure handling .\ntype FailureHandlingKind string\n\nconst (\n\t// FailureHandlingKindAbort applying the workspace change is simply aborted if one of the changes provided\n\t// fails. All operations executed before the failing operation stay executed.\n\tFailureHandlingKindAbort FailureHandlingKind = \"abort\"\n\n\t// FailureHandlingKindTransactional all operations are executed transactional. That means they either all\n\t// succeed or no changes at all are applied to the workspace.\n\tFailureHandlingKindTransactional FailureHandlingKind = \"transactional\"\n\n\t// FailureHandlingKindTextOnlyTransactional if the workspace edit contains only textual file changes they are executed transactional.\n\t// If resource changes (create, rename or delete file) are part of the change the failure\n\t// handling strategy is abort.\n\tFailureHandlingKindTextOnlyTransactional FailureHandlingKind = \"textOnlyTransactional\"\n\n\t// FailureHandlingKindUndo the client tries to undo the operations already executed. But there is no\n\t// guarantee that this is succeeding.\n\tFailureHandlingKindUndo FailureHandlingKind = \"undo\"\n)\n\n// WorkspaceClientCapabilitiesWorkspaceEditChangeAnnotationSupport is the ChangeAnnotationSupport of WorkspaceClientCapabilitiesWorkspaceEdit.\n//\n// @since 3.16.0.\ntype WorkspaceClientCapabilitiesWorkspaceEditChangeAnnotationSupport struct {\n\t// GroupsOnLabel whether the client groups edits with equal labels into tree nodes,\n\t// for instance all edits labeled with \"Changes in Strings\" would\n\t// be a tree node.\n\tGroupsOnLabel bool `json:\"groupsOnLabel,omitempty\"`\n}\n\n// DidChangeConfigurationWorkspaceClientCapabilities capabilities specific to the \"workspace/didChangeConfiguration\" notification.\n//\n// @since 3.16.0.\ntype DidChangeConfigurationWorkspaceClientCapabilities struct {\n\t// DynamicRegistration whether the did change configuration notification supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// DidChangeWatchedFilesWorkspaceClientCapabilities capabilities specific to the \"workspace/didChangeWatchedFiles\" notification.\n//\n// @since 3.16.0.\ntype DidChangeWatchedFilesWorkspaceClientCapabilities struct {\n\t// Did change watched files notification supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// WorkspaceSymbolClientCapabilities capabilities specific to the `workspace/symbol` request.\n//\n// WorkspaceSymbolClientCapabilities is the workspace symbol request is sent from the client to the server to\n// list project-wide symbols matching the query string.\ntype WorkspaceSymbolClientCapabilities struct {\n\t// DynamicRegistration is the Symbol request supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// SymbolKindCapabilities is the specific capabilities for the SymbolKindCapabilities in the \"workspace/symbol\" request.\n\tSymbolKind *SymbolKindCapabilities `json:\"symbolKind,omitempty\"`\n\n\t// TagSupport is the client supports tags on `SymbolInformation`.\n\t// Clients supporting tags have to handle unknown tags gracefully.\n\t//\n\t// @since 3.16.0\n\tTagSupport *TagSupportCapabilities `json:\"tagSupport,omitempty\"`\n}\n\ntype SymbolKindCapabilities struct {\n\t// ValueSet is the symbol kind values the client supports. When this\n\t// property exists the client also guarantees that it will\n\t// handle values outside its set gracefully and falls back\n\t// to a default value when unknown.\n\t//\n\t// If this property is not present the client only supports\n\t// the symbol kinds from `File` to `Array` as defined in\n\t// the initial version of the protocol.\n\tValueSet []SymbolKind `json:\"valueSet,omitempty\"`\n}\n\ntype TagSupportCapabilities struct {\n\t// ValueSet is the tags supported by the client.\n\tValueSet []SymbolTag `json:\"valueSet,omitempty\"`\n}\n\n// ExecuteCommandClientCapabilities capabilities specific to the \"workspace/executeCommand\" request.\ntype ExecuteCommandClientCapabilities struct {\n\t// DynamicRegistration Execute command supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// SemanticTokensWorkspaceClientCapabilities capabilities specific to the \"workspace/semanticToken\" request.\n//\n// @since 3.16.0.\ntype SemanticTokensWorkspaceClientCapabilities struct {\n\t// RefreshSupport whether the client implementation supports a refresh request sent from\n\t// the server to the client.\n\t//\n\t// Note that this event is global and will force the client to refresh all\n\t// semantic tokens currently shown. It should be used with absolute care\n\t// and is useful for situation where a server for example detect a project\n\t// wide change that requires such a calculation.\n\tRefreshSupport bool `json:\"refreshSupport,omitempty\"`\n}\n\n// CodeLensWorkspaceClientCapabilities capabilities specific to the \"workspace/codeLens\" request.\n//\n// @since 3.16.0.\ntype CodeLensWorkspaceClientCapabilities struct {\n\t// RefreshSupport whether the client implementation supports a refresh request sent from the\n\t// server to the client.\n\t//\n\t// Note that this event is global and will force the client to refresh all\n\t// code lenses currently shown. It should be used with absolute care and is\n\t// useful for situation where a server for example detect a project wide\n\t// change that requires such a calculation.\n\tRefreshSupport bool `json:\"refreshSupport,omitempty\"`\n}\n\n// WorkspaceClientCapabilitiesFileOperations capabilities specific to the fileOperations.\n//\n// @since 3.16.0.\ntype WorkspaceClientCapabilitiesFileOperations struct {\n\t// DynamicRegistration whether the client supports dynamic registration for file\n\t// requests/notifications.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// DidCreate is the client has support for sending didCreateFiles notifications.\n\tDidCreate bool `json:\"didCreate,omitempty\"`\n\n\t// WillCreate is the client has support for sending willCreateFiles requests.\n\tWillCreate bool `json:\"willCreate,omitempty\"`\n\n\t// DidRename is the client has support for sending didRenameFiles notifications.\n\tDidRename bool `json:\"didRename,omitempty\"`\n\n\t// WillRename is the client has support for sending willRenameFiles requests.\n\tWillRename bool `json:\"willRename,omitempty\"`\n\n\t// DidDelete is the client has support for sending didDeleteFiles notifications.\n\tDidDelete bool `json:\"didDelete,omitempty\"`\n\n\t// WillDelete is the client has support for sending willDeleteFiles requests.\n\tWillDelete bool `json:\"willDelete,omitempty\"`\n}\n\n// TextDocumentClientCapabilities Text document specific client capabilities.\ntype TextDocumentClientCapabilities struct {\n\t// Synchronization defines which synchronization capabilities the client supports.\n\tSynchronization *TextDocumentSyncClientCapabilities `json:\"synchronization,omitempty\"`\n\n\t// Completion Capabilities specific to the \"textDocument/completion\".\n\tCompletion *CompletionTextDocumentClientCapabilities `json:\"completion,omitempty\"`\n\n\t// Hover capabilities specific to the \"textDocument/hover\".\n\tHover *HoverTextDocumentClientCapabilities `json:\"hover,omitempty\"`\n\n\t// SignatureHelp capabilities specific to the \"textDocument/signatureHelp\".\n\tSignatureHelp *SignatureHelpTextDocumentClientCapabilities `json:\"signatureHelp,omitempty\"`\n\n\t// Declaration capabilities specific to the \"textDocument/declaration\".\n\tDeclaration *DeclarationTextDocumentClientCapabilities `json:\"declaration,omitempty\"`\n\n\t// Definition capabilities specific to the \"textDocument/definition\".\n\t//\n\t// @since 3.14.0.\n\tDefinition *DefinitionTextDocumentClientCapabilities `json:\"definition,omitempty\"`\n\n\t// TypeDefinition capabilities specific to the \"textDocument/typeDefinition\".\n\t//\n\t// @since 3.6.0.\n\tTypeDefinition *TypeDefinitionTextDocumentClientCapabilities `json:\"typeDefinition,omitempty\"`\n\n\t// Implementation capabilities specific to the \"textDocument/implementation\".\n\t//\n\t// @since 3.6.0.\n\tImplementation *ImplementationTextDocumentClientCapabilities `json:\"implementation,omitempty\"`\n\n\t// References capabilities specific to the \"textDocument/references\".\n\tReferences *ReferencesTextDocumentClientCapabilities `json:\"references,omitempty\"`\n\n\t// DocumentHighlight capabilities specific to the \"textDocument/documentHighlight\".\n\tDocumentHighlight *DocumentHighlightClientCapabilities `json:\"documentHighlight,omitempty\"`\n\n\t// DocumentSymbol capabilities specific to the \"textDocument/documentSymbol\".\n\tDocumentSymbol *DocumentSymbolClientCapabilities `json:\"documentSymbol,omitempty\"`\n\n\t// CodeAction capabilities specific to the \"textDocument/codeAction\".\n\tCodeAction *CodeActionClientCapabilities `json:\"codeAction,omitempty\"`\n\n\t// CodeLens capabilities specific to the \"textDocument/codeLens\".\n\tCodeLens *CodeLensClientCapabilities `json:\"codeLens,omitempty\"`\n\n\t// DocumentLink capabilities specific to the \"textDocument/documentLink\".\n\tDocumentLink *DocumentLinkClientCapabilities `json:\"documentLink,omitempty\"`\n\n\t// ColorProvider capabilities specific to the \"textDocument/documentColor\" and the\n\t// \"textDocument/colorPresentation\" request.\n\t//\n\t// @since 3.6.0.\n\tColorProvider *DocumentColorClientCapabilities `json:\"colorProvider,omitempty\"`\n\n\t// Formatting Capabilities specific to the \"textDocument/formatting\" request.\n\tFormatting *DocumentFormattingClientCapabilities `json:\"formatting,omitempty\"`\n\n\t// RangeFormatting Capabilities specific to the \"textDocument/rangeFormatting\" request.\n\tRangeFormatting *DocumentRangeFormattingClientCapabilities `json:\"rangeFormatting,omitempty\"`\n\n\t// OnTypeFormatting Capabilities specific to the \"textDocument/onTypeFormatting\" request.\n\tOnTypeFormatting *DocumentOnTypeFormattingClientCapabilities `json:\"onTypeFormatting,omitempty\"`\n\n\t// PublishDiagnostics capabilities specific to \"textDocument/publishDiagnostics\".\n\tPublishDiagnostics *PublishDiagnosticsClientCapabilities `json:\"publishDiagnostics,omitempty\"`\n\n\t// Rename capabilities specific to the \"textDocument/rename\".\n\tRename *RenameClientCapabilities `json:\"rename,omitempty\"`\n\n\t// FoldingRange capabilities specific to \"textDocument/foldingRange\" requests.\n\t//\n\t// @since 3.10.0.\n\tFoldingRange *FoldingRangeClientCapabilities `json:\"foldingRange,omitempty\"`\n\n\t// SelectionRange capabilities specific to \"textDocument/selectionRange\" requests.\n\t//\n\t// @since 3.15.0.\n\tSelectionRange *SelectionRangeClientCapabilities `json:\"selectionRange,omitempty\"`\n\n\t// CallHierarchy capabilities specific to the various call hierarchy requests.\n\t//\n\t// @since 3.16.0.\n\tCallHierarchy *CallHierarchyClientCapabilities `json:\"callHierarchy,omitempty\"`\n\n\t// SemanticTokens capabilities specific to the various semantic token requests.\n\t//\n\t// @since 3.16.0.\n\tSemanticTokens *SemanticTokensClientCapabilities `json:\"semanticTokens,omitempty\"`\n\n\t// LinkedEditingRange capabilities specific to the \"textDocument/linkedEditingRange\" request.\n\t//\n\t// @since 3.16.0.\n\tLinkedEditingRange *LinkedEditingRangeClientCapabilities `json:\"linkedEditingRange,omitempty\"`\n\n\t// Moniker capabilities specific to the \"textDocument/moniker\" request.\n\t//\n\t// @since 3.16.0.\n\tMoniker *MonikerClientCapabilities `json:\"moniker,omitempty\"`\n}\n\n// TextDocumentSyncClientCapabilities defines which synchronization capabilities the client supports.\ntype TextDocumentSyncClientCapabilities struct {\n\t// DynamicRegistration whether text document synchronization supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// WillSave is the client supports sending will save notifications.\n\tWillSave bool `json:\"willSave,omitempty\"`\n\n\t// WillSaveWaitUntil is the client supports sending a will save request and\n\t// waits for a response providing text edits which will\n\t// be applied to the document before it is saved.\n\tWillSaveWaitUntil bool `json:\"willSaveWaitUntil,omitempty\"`\n\n\t// DidSave is the client supports did save notifications.\n\tDidSave bool `json:\"didSave,omitempty\"`\n}\n\n// CompletionTextDocumentClientCapabilities Capabilities specific to the \"textDocument/completion\".\ntype CompletionTextDocumentClientCapabilities struct {\n\t// Whether completion supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// The client supports the following `CompletionItem` specific\n\t// capabilities.\n\tCompletionItem *CompletionTextDocumentClientCapabilitiesItem `json:\"completionItem,omitempty\"`\n\n\tCompletionItemKind *CompletionTextDocumentClientCapabilitiesItemKind `json:\"completionItemKind,omitempty\"`\n\n\t// ContextSupport is the client supports to send additional context information for a\n\t// `textDocument/completion` request.\n\tContextSupport bool `json:\"contextSupport,omitempty\"`\n}\n\n// CompletionTextDocumentClientCapabilitiesItem is the client supports the following \"CompletionItem\" specific\n// capabilities.\ntype CompletionTextDocumentClientCapabilitiesItem struct {\n\t// SnippetSupport client supports snippets as insert text.\n\t//\n\t// A snippet can define tab stops and placeholders with `$1`, `$2`\n\t// and `${3:foo}`. `$0` defines the final tab stop, it defaults to\n\t// the end of the snippet. Placeholders with equal identifiers are linked,\n\t// that is typing in one will update others too.\n\tSnippetSupport bool `json:\"snippetSupport,omitempty\"`\n\n\t// CommitCharactersSupport client supports commit characters on a completion item.\n\tCommitCharactersSupport bool `json:\"commitCharactersSupport,omitempty\"`\n\n\t// DocumentationFormat client supports the follow content formats for the documentation\n\t// property. The order describes the preferred format of the client.\n\tDocumentationFormat []MarkupKind `json:\"documentationFormat,omitempty\"`\n\n\t// DeprecatedSupport client supports the deprecated property on a completion item.\n\tDeprecatedSupport bool `json:\"deprecatedSupport,omitempty\"`\n\n\t// PreselectSupport client supports the preselect property on a completion item.\n\tPreselectSupport bool `json:\"preselectSupport,omitempty\"`\n\n\t// TagSupport is the client supports the tag property on a completion item.\n\t//\n\t// Clients supporting tags have to handle unknown tags gracefully.\n\t// Clients especially need to preserve unknown tags when sending\n\t// a completion item back to the server in a resolve call.\n\t//\n\t// @since 3.15.0.\n\tTagSupport *CompletionTextDocumentClientCapabilitiesItemTagSupport `json:\"tagSupport,omitempty\"`\n\n\t// InsertReplaceSupport client supports insert replace edit to control different behavior if\n\t// a completion item is inserted in the text or should replace text.\n\t//\n\t// @since 3.16.0.\n\tInsertReplaceSupport bool `json:\"insertReplaceSupport,omitempty\"`\n\n\t// ResolveSupport indicates which properties a client can resolve lazily on a\n\t// completion item. Before version 3.16.0 only the predefined properties\n\t// `documentation` and `details` could be resolved lazily.\n\t//\n\t// @since 3.16.0.\n\tResolveSupport *CompletionTextDocumentClientCapabilitiesItemResolveSupport `json:\"resolveSupport,omitempty\"`\n\n\t// InsertTextModeSupport is the client supports the `insertTextMode` property on\n\t// a completion item to override the whitespace handling mode\n\t// as defined by the client (see `insertTextMode`).\n\t//\n\t// @since 3.16.0.\n\tInsertTextModeSupport *CompletionTextDocumentClientCapabilitiesItemInsertTextModeSupport `json:\"insertTextModeSupport,omitempty\"`\n}\n\n// CompletionTextDocumentClientCapabilitiesItemTagSupport specific capabilities for the \"TagSupport\" in the \"textDocument/completion\" request.\n//\n// @since 3.15.0.\ntype CompletionTextDocumentClientCapabilitiesItemTagSupport struct {\n\t// ValueSet is the tags supported by the client.\n\t//\n\t// @since 3.15.0.\n\tValueSet []CompletionItemTag `json:\"valueSet,omitempty\"`\n}\n\n// CompletionTextDocumentClientCapabilitiesItemResolveSupport specific capabilities for the ResolveSupport in the CompletionTextDocumentClientCapabilitiesItem.\n//\n// @since 3.16.0.\ntype CompletionTextDocumentClientCapabilitiesItemResolveSupport struct {\n\t// Properties is the properties that a client can resolve lazily.\n\tProperties []string `json:\"properties\"`\n}\n\n// CompletionTextDocumentClientCapabilitiesItemInsertTextModeSupport specific capabilities for the InsertTextModeSupport in the CompletionTextDocumentClientCapabilitiesItem.\n//\n// @since 3.16.0.\ntype CompletionTextDocumentClientCapabilitiesItemInsertTextModeSupport struct {\n\t// ValueSet is the tags supported by the client.\n\t//\n\t// @since 3.16.0.\n\tValueSet []InsertTextMode `json:\"valueSet,omitempty\"`\n}\n\n// CompletionTextDocumentClientCapabilitiesItemKind specific capabilities for the \"CompletionItemKind\" in the \"textDocument/completion\" request.\ntype CompletionTextDocumentClientCapabilitiesItemKind struct {\n\t// The completion item kind values the client supports. When this\n\t// property exists the client also guarantees that it will\n\t// handle values outside its set gracefully and falls back\n\t// to a default value when unknown.\n\t//\n\t// If this property is not present the client only supports\n\t// the completion items kinds from `Text` to `Reference` as defined in\n\t// the initial version of the protocol.\n\t//\n\tValueSet []CompletionItemKind `json:\"valueSet,omitempty\"`\n}\n\n// HoverTextDocumentClientCapabilities capabilities specific to the \"textDocument/hover\".\ntype HoverTextDocumentClientCapabilities struct {\n\t// DynamicRegistration whether hover supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// ContentFormat is the client supports the follow content formats for the content\n\t// property. The order describes the preferred format of the client.\n\tContentFormat []MarkupKind `json:\"contentFormat,omitempty\"`\n}\n\n// SignatureHelpTextDocumentClientCapabilities capabilities specific to the \"textDocument/signatureHelp\".\ntype SignatureHelpTextDocumentClientCapabilities struct {\n\t// DynamicRegistration whether signature help supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// SignatureInformation is the client supports the following \"SignatureInformation\"\n\t// specific properties.\n\tSignatureInformation *TextDocumentClientCapabilitiesSignatureInformation `json:\"signatureInformation,omitempty\"`\n\n\t// ContextSupport is the client supports to send additional context information for a \"textDocument/signatureHelp\" request.\n\t//\n\t// A client that opts into contextSupport will also support the \"retriggerCharacters\" on \"SignatureHelpOptions\".\n\t//\n\t// @since 3.15.0.\n\tContextSupport bool `json:\"contextSupport,omitempty\"`\n}\n\n// TextDocumentClientCapabilitiesSignatureInformation is the client supports the following \"SignatureInformation\"\n// specific properties.\ntype TextDocumentClientCapabilitiesSignatureInformation struct {\n\t// DocumentationFormat is the client supports the follow content formats for the documentation\n\t// property. The order describes the preferred format of the client.\n\tDocumentationFormat []MarkupKind `json:\"documentationFormat,omitempty\"`\n\n\t// ParameterInformation is the Client capabilities specific to parameter information.\n\tParameterInformation *TextDocumentClientCapabilitiesParameterInformation `json:\"parameterInformation,omitempty\"`\n\n\t// ActiveParameterSupport is the client supports the `activeParameter` property on\n\t// `SignatureInformation` literal.\n\t//\n\t// @since 3.16.0.\n\tActiveParameterSupport bool `json:\"activeParameterSupport,omitempty\"`\n}\n\n// TextDocumentClientCapabilitiesParameterInformation is the client capabilities specific to parameter information.\ntype TextDocumentClientCapabilitiesParameterInformation struct {\n\t// LabelOffsetSupport is the client supports processing label offsets instead of a\n\t// simple label string.\n\t//\n\t// @since 3.14.0.\n\tLabelOffsetSupport bool `json:\"labelOffsetSupport,omitempty\"`\n}\n\n// DeclarationTextDocumentClientCapabilities capabilities specific to the \"textDocument/declaration\".\ntype DeclarationTextDocumentClientCapabilities struct {\n\t// DynamicRegistration whether declaration supports dynamic registration. If this is set to `true`\n\t// the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\n\t// return value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// LinkSupport is the client supports additional metadata in the form of declaration links.\n\t//\n\t// @since 3.14.0.\n\tLinkSupport bool `json:\"linkSupport,omitempty\"`\n}\n\n// DefinitionTextDocumentClientCapabilities capabilities specific to the \"textDocument/definition\".\n//\n// @since 3.14.0.\ntype DefinitionTextDocumentClientCapabilities struct {\n\t// DynamicRegistration whether definition supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// LinkSupport is the client supports additional metadata in the form of definition links.\n\tLinkSupport bool `json:\"linkSupport,omitempty\"`\n}\n\n// TypeDefinitionTextDocumentClientCapabilities capabilities specific to the \"textDocument/typeDefinition\".\n//\n// @since 3.6.0.\ntype TypeDefinitionTextDocumentClientCapabilities struct {\n\t// DynamicRegistration whether typeDefinition supports dynamic registration. If this is set to `true`\n\t// the client supports the new \"(TextDocumentRegistrationOptions & StaticRegistrationOptions)\"\n\t// return value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// LinkSupport is the client supports additional metadata in the form of definition links.\n\t//\n\t// @since 3.14.0\n\tLinkSupport bool `json:\"linkSupport,omitempty\"`\n}\n\n// ImplementationTextDocumentClientCapabilities capabilities specific to the \"textDocument/implementation\".\n//\n// @since 3.6.0.\ntype ImplementationTextDocumentClientCapabilities struct {\n\t// DynamicRegistration whether implementation supports dynamic registration. If this is set to `true`\n\t// the client supports the new \"(TextDocumentRegistrationOptions & StaticRegistrationOptions)\"\n\t// return value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// LinkSupport is the client supports additional metadata in the form of definition links.\n\t//\n\t// @since 3.14.0\n\tLinkSupport bool `json:\"linkSupport,omitempty\"`\n}\n\n// ReferencesTextDocumentClientCapabilities capabilities specific to the \"textDocument/references\".\ntype ReferencesTextDocumentClientCapabilities struct {\n\t// DynamicRegistration whether references supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// DocumentHighlightClientCapabilities capabilities specific to the \"textDocument/documentHighlight\".\ntype DocumentHighlightClientCapabilities struct {\n\t// DynamicRegistration Whether document highlight supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// DocumentSymbolClientCapabilities capabilities specific to the \"textDocument/documentSymbol\".\ntype DocumentSymbolClientCapabilities struct {\n\t// DynamicRegistration whether document symbol supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// SymbolKind specific capabilities for the \"SymbolKindCapabilities\".\n\tSymbolKind *SymbolKindCapabilities `json:\"symbolKind,omitempty\"`\n\n\t// HierarchicalDocumentSymbolSupport is the client support hierarchical document symbols.\n\tHierarchicalDocumentSymbolSupport bool `json:\"hierarchicalDocumentSymbolSupport,omitempty\"`\n\n\t// TagSupport is the client supports tags on \"SymbolInformation\". Tags are supported on\n\t// \"DocumentSymbol\" if \"HierarchicalDocumentSymbolSupport\" is set to true.\n\t// Clients supporting tags have to handle unknown tags gracefully.\n\t//\n\t// @since 3.16.0.\n\tTagSupport *DocumentSymbolClientCapabilitiesTagSupport `json:\"tagSupport,omitempty\"`\n\n\t// LabelSupport is the client supports an additional label presented in the UI when\n\t// registering a document symbol provider.\n\t//\n\t// @since 3.16.0.\n\tLabelSupport bool `json:\"labelSupport,omitempty\"`\n}\n\n// DocumentSymbolClientCapabilitiesTagSupport TagSupport in the DocumentSymbolClientCapabilities.\n//\n// @since 3.16.0.\ntype DocumentSymbolClientCapabilitiesTagSupport struct {\n\t// ValueSet is the tags supported by the client.\n\tValueSet []SymbolTag `json:\"valueSet\"`\n}\n\n// CodeActionClientCapabilities capabilities specific to the \"textDocument/codeAction\".\ntype CodeActionClientCapabilities struct {\n\t// DynamicRegistration whether code action supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// CodeActionLiteralSupport is the client support code action literals as a valid\n\t// response of the \"textDocument/codeAction\" request.\n\t//\n\t// @since 3.8.0\n\tCodeActionLiteralSupport *CodeActionClientCapabilitiesLiteralSupport `json:\"codeActionLiteralSupport,omitempty\"`\n\n\t// IsPreferredSupport whether code action supports the \"isPreferred\" property.\n\t//\n\t// @since 3.15.0.\n\tIsPreferredSupport bool `json:\"isPreferredSupport,omitempty\"`\n\n\t// DisabledSupport whether code action supports the `disabled` property.\n\t//\n\t// @since 3.16.0.\n\tDisabledSupport bool `json:\"disabledSupport,omitempty\"`\n\n\t// DataSupport whether code action supports the `data` property which is\n\t// preserved between a `textDocument/codeAction` and a\n\t// `codeAction/resolve` request.\n\t//\n\t// @since 3.16.0.\n\tDataSupport bool `json:\"dataSupport,omitempty\"`\n\n\t// ResolveSupport whether the client supports resolving additional code action\n\t// properties via a separate `codeAction/resolve` request.\n\t//\n\t// @since 3.16.0.\n\tResolveSupport *CodeActionClientCapabilitiesResolveSupport `json:\"resolveSupport,omitempty\"`\n\n\t// HonorsChangeAnnotations whether the client honors the change annotations in\n\t// text edits and resource operations returned via the\n\t// `CodeAction#edit` property by for example presenting\n\t// the workspace edit in the user interface and asking\n\t// for confirmation.\n\t//\n\t// @since 3.16.0.\n\tHonorsChangeAnnotations bool `json:\"honorsChangeAnnotations,omitempty\"`\n}\n\n// CodeActionClientCapabilitiesLiteralSupport is the client support code action literals as a valid response of the \"textDocument/codeAction\" request.\ntype CodeActionClientCapabilitiesLiteralSupport struct {\n\t// CodeActionKind is the code action kind is support with the following value\n\t// set.\n\tCodeActionKind *CodeActionClientCapabilitiesKind `json:\"codeActionKind\"`\n}\n\n// CodeActionClientCapabilitiesKind is the code action kind is support with the following value set.\ntype CodeActionClientCapabilitiesKind struct {\n\t// ValueSet is the code action kind values the client supports. When this\n\t// property exists the client also guarantees that it will\n\t// handle values outside its set gracefully and falls back\n\t// to a default value when unknown.\n\tValueSet []CodeActionKind `json:\"valueSet\"`\n}\n\n// CodeActionClientCapabilitiesResolveSupport ResolveSupport in the CodeActionClientCapabilities.\n//\n// @since 3.16.0.\ntype CodeActionClientCapabilitiesResolveSupport struct {\n\t// Properties is the properties that a client can resolve lazily.\n\tProperties []string `json:\"properties\"`\n}\n\n// CodeLensClientCapabilities capabilities specific to the \"textDocument/codeLens\".\ntype CodeLensClientCapabilities struct {\n\t// DynamicRegistration Whether code lens supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// DocumentLinkClientCapabilities capabilities specific to the \"textDocument/documentLink\".\ntype DocumentLinkClientCapabilities struct {\n\t// DynamicRegistration whether document link supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// TooltipSupport whether the client supports the \"tooltip\" property on \"DocumentLink\".\n\t//\n\t// @since 3.15.0.\n\tTooltipSupport bool `json:\"tooltipSupport,omitempty\"`\n}\n\n// DocumentColorClientCapabilities capabilities specific to the \"textDocument/documentColor\" and the\n// \"textDocument/colorPresentation\" request.\n//\n// @since 3.6.0.\ntype DocumentColorClientCapabilities struct {\n\t// DynamicRegistration whether colorProvider supports dynamic registration. If this is set to `true`\n\t// the client supports the new \"(ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)\"\n\t// return value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// DocumentFormattingClientCapabilities capabilities specific to the \"textDocument/formatting\".\ntype DocumentFormattingClientCapabilities struct {\n\t// DynamicRegistration whether code lens supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// DocumentRangeFormattingClientCapabilities capabilities specific to the \"textDocument/rangeFormatting\".\ntype DocumentRangeFormattingClientCapabilities struct {\n\t// DynamicRegistration whether code lens supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// DocumentOnTypeFormattingClientCapabilities capabilities specific to the \"textDocument/onTypeFormatting\".\ntype DocumentOnTypeFormattingClientCapabilities struct {\n\t// DynamicRegistration whether code lens supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// PublishDiagnosticsClientCapabilities capabilities specific to \"textDocument/publishDiagnostics\".\ntype PublishDiagnosticsClientCapabilities struct {\n\t// RelatedInformation whether the clients accepts diagnostics with related information.\n\tRelatedInformation bool `json:\"relatedInformation,omitempty\"`\n\n\t// TagSupport clients supporting tags have to handle unknown tags gracefully.\n\t//\n\t// @since 3.15.0.\n\tTagSupport *PublishDiagnosticsClientCapabilitiesTagSupport `json:\"tagSupport,omitempty\"`\n\n\t// VersionSupport whether the client interprets the version property of the\n\t// \"textDocument/publishDiagnostics\" notification`s parameter.\n\t//\n\t// @since 3.15.0.\n\tVersionSupport bool `json:\"versionSupport,omitempty\"`\n\n\t// CodeDescriptionSupport client supports a codeDescription property\n\t//\n\t// @since 3.16.0.\n\tCodeDescriptionSupport bool `json:\"codeDescriptionSupport,omitempty\"`\n\n\t// DataSupport whether code action supports the `data` property which is\n\t// preserved between a `textDocument/publishDiagnostics` and\n\t// `textDocument/codeAction` request.\n\t//\n\t// @since 3.16.0.\n\tDataSupport bool `json:\"dataSupport,omitempty\"`\n}\n\n// PublishDiagnosticsClientCapabilitiesTagSupport is the client capacity of TagSupport.\n//\n// @since 3.15.0.\ntype PublishDiagnosticsClientCapabilitiesTagSupport struct {\n\t// ValueSet is the tags supported by the client.\n\tValueSet []DiagnosticTag `json:\"valueSet\"`\n}\n\n// RenameClientCapabilities capabilities specific to the \"textDocument/rename\".\ntype RenameClientCapabilities struct {\n\t// DynamicRegistration whether rename supports dynamic registration.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// PrepareSupport is the client supports testing for validity of rename operations\n\t// before execution.\n\tPrepareSupport bool `json:\"prepareSupport,omitempty\"`\n\n\t// PrepareSupportDefaultBehavior client supports the default behavior result\n\t// (`{ defaultBehavior: boolean }`).\n\t//\n\t// The value indicates the default behavior used by the\n\t// client.\n\t//\n\t// @since 3.16.0.\n\tPrepareSupportDefaultBehavior PrepareSupportDefaultBehavior `json:\"prepareSupportDefaultBehavior,omitempty\"`\n\n\t// HonorsChangeAnnotations whether th client honors the change annotations in\n\t// text edits and resource operations returned via the\n\t// rename request's workspace edit by for example presenting\n\t// the workspace edit in the user interface and asking\n\t// for confirmation.\n\t//\n\t// @since 3.16.0.\n\tHonorsChangeAnnotations bool `json:\"honorsChangeAnnotations,omitempty\"`\n}\n\n// PrepareSupportDefaultBehavior default behavior of PrepareSupport.\n//\n// @since 3.16.0.\ntype PrepareSupportDefaultBehavior float64\n\n// list of PrepareSupportDefaultBehavior.\nconst (\n\t// PrepareSupportDefaultBehaviorIdentifier is the client's default behavior is to select the identifier\n\t// according the to language's syntax rule.\n\tPrepareSupportDefaultBehaviorIdentifier PrepareSupportDefaultBehavior = 1\n)\n\n// String returns a string representation of the PrepareSupportDefaultBehavior.\nfunc (k PrepareSupportDefaultBehavior) String() string {\n\tswitch k {\n\tcase PrepareSupportDefaultBehaviorIdentifier:\n\t\treturn \"Identifier\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// FoldingRangeClientCapabilities capabilities specific to \"textDocument/foldingRange\" requests.\n//\n// @since 3.10.0.\ntype FoldingRangeClientCapabilities struct {\n\t// DynamicRegistration whether implementation supports dynamic registration for folding range providers. If this is set to `true`\n\t// the client supports the new \"(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)\"\n\t// return value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// RangeLimit is the maximum number of folding ranges that the client prefers to receive per document. The value serves as a\n\t// hint, servers are free to follow the limit.\n\tRangeLimit uint32 `json:\"rangeLimit,omitempty\"`\n\n\t// LineFoldingOnly if set, the client signals that it only supports folding complete lines. If set, client will\n\t// ignore specified \"startCharacter\" and \"endCharacter\" properties in a FoldingRange.\n\tLineFoldingOnly bool `json:\"lineFoldingOnly,omitempty\"`\n}\n\n// SelectionRangeClientCapabilities capabilities specific to \"textDocument/selectionRange\" requests.\n//\n// @since 3.16.0.\ntype SelectionRangeClientCapabilities struct {\n\t// DynamicRegistration whether implementation supports dynamic registration for selection range providers. If this is set to `true`\n\t// the client supports the new \"(SelectionRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)\"\n\t// return value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// CallHierarchyClientCapabilities capabilities specific to \"textDocument/callHierarchy\" requests.\n//\n// @since 3.16.0.\ntype CallHierarchyClientCapabilities struct {\n\t// DynamicRegistration whether implementation supports dynamic registration. If this is set to\n\t// `true` the client supports the new `(TextDocumentRegistrationOptions &\n\t// StaticRegistrationOptions)` return value for the corresponding server\n\t// capability as well.}\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// SemanticTokensClientCapabilities capabilities specific to the \"textDocument.semanticTokens\" request.\n//\n// @since 3.16.0.\ntype SemanticTokensClientCapabilities struct {\n\t// DynamicRegistration whether implementation supports dynamic registration. If this is set to\n\t// `true` the client supports the new `(TextDocumentRegistrationOptions &\n\t// StaticRegistrationOptions)` return value for the corresponding server\n\t// capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n\n\t// Requests which requests the client supports and might send to the server\n\t// depending on the server's capability. Please note that clients might not\n\t// show semantic tokens or degrade some of the user experience if a range\n\t// or full request is advertised by the client but not provided by the\n\t// server. If for example the client capability `requests.full` and\n\t// `request.range` are both set to true but the server only provides a\n\t// range provider the client might not render a minimap correctly or might\n\t// even decide to not show any semantic tokens at all.\n\tRequests SemanticTokensWorkspaceClientCapabilitiesRequests `json:\"requests\"`\n\n\t// TokenTypes is the token types that the client supports.\n\tTokenTypes []string `json:\"tokenTypes\"`\n\n\t// TokenModifiers is the token modifiers that the client supports.\n\tTokenModifiers []string `json:\"tokenModifiers\"`\n\n\t// Formats is the formats the clients supports.\n\tFormats []TokenFormat `json:\"formats\"`\n\n\t// OverlappingTokenSupport whether the client supports tokens that can overlap each other.\n\tOverlappingTokenSupport bool `json:\"overlappingTokenSupport,omitempty\"`\n\n\t// MultilineTokenSupport whether the client supports tokens that can span multiple lines.\n\tMultilineTokenSupport bool `json:\"multilineTokenSupport,omitempty\"`\n}\n\n// SemanticTokensWorkspaceClientCapabilitiesRequests capabilities specific to the \"textDocument/semanticTokens/xxx\" request.\n//\n// @since 3.16.0.\ntype SemanticTokensWorkspaceClientCapabilitiesRequests struct {\n\t// Range is the client will send the \"textDocument/semanticTokens/range\" request\n\t// if the server provides a corresponding handler.\n\tRange bool `json:\"range,omitempty\"`\n\n\t// Full is the client will send the \"textDocument/semanticTokens/full\" request\n\t// if the server provides a corresponding handler. The client will send the\n\t// `textDocument/semanticTokens/full/delta` request if the server provides a\n\t// corresponding handler.\n\tFull any `json:\"full,omitempty\"`\n}\n\n// LinkedEditingRangeClientCapabilities capabilities specific to \"textDocument/linkedEditingRange\" requests.\n//\n// @since 3.16.0.\ntype LinkedEditingRangeClientCapabilities struct {\n\t// DynamicRegistration whether implementation supports dynamic registration.\n\t// If this is set to `true` the client supports the new\n\t// `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`\n\t// return value for the corresponding server capability as well.\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// MonikerClientCapabilities capabilities specific to the \"textDocument/moniker\" request.\n//\n// @since 3.16.0.\ntype MonikerClientCapabilities struct {\n\t// DynamicRegistration whether implementation supports dynamic registration. If this is set to\n\t// `true` the client supports the new `(TextDocumentRegistrationOptions &\n\t// StaticRegistrationOptions)` return value for the corresponding server\n\t// capability as well.// DynamicRegistration whether implementation supports dynamic registration. If this is set to\n\tDynamicRegistration bool `json:\"dynamicRegistration,omitempty\"`\n}\n\n// WindowClientCapabilities represents a WindowClientCapabilities specific client capabilities.\n//\n// @since 3.15.0.\ntype WindowClientCapabilities struct {\n\t// WorkDoneProgress whether client supports handling progress notifications. If set servers are allowed to\n\t// report in \"workDoneProgress\" property in the request specific server capabilities.\n\t//\n\t// @since 3.15.0.\n\tWorkDoneProgress bool `json:\"workDoneProgress,omitempty\"`\n\n\t// ShowMessage capabilities specific to the showMessage request.\n\t//\n\t// @since 3.16.0.\n\tShowMessage *ShowMessageRequestClientCapabilities `json:\"showMessage,omitempty\"`\n\n\t// ShowDocument client capabilities for the show document request.\n\t//\n\t// @since 3.16.0.\n\tShowDocument *ShowDocumentClientCapabilities `json:\"showDocument,omitempty\"`\n}\n\n// ShowMessageRequestClientCapabilities show message request client capabilities.\n//\n// @since 3.16.0.\ntype ShowMessageRequestClientCapabilities struct {\n\t// MessageActionItem capabilities specific to the \"MessageActionItem\" type.\n\tMessageActionItem *ShowMessageRequestClientCapabilitiesMessageActionItem `json:\"messageActionItem,omitempty\"`\n}\n\n// ShowMessageRequestClientCapabilitiesMessageActionItem capabilities specific to the \"MessageActionItem\" type.\n//\n// @since 3.16.0.\ntype ShowMessageRequestClientCapabilitiesMessageActionItem struct {\n\t// AdditionalPropertiesSupport whether the client supports additional attributes which\n\t// are preserved and sent back to the server in the\n\t// request's response.\n\tAdditionalPropertiesSupport bool `json:\"additionalPropertiesSupport,omitempty\"`\n}\n\n// ShowDocumentClientCapabilities client capabilities for the show document request.\n//\n// @since 3.16.0.\ntype ShowDocumentClientCapabilities struct {\n\t// Support is the client has support for the show document\n\t// request.\n\tSupport bool `json:\"support\"`\n}\n\n// GeneralClientCapabilities represents a General specific client capabilities.\n//\n// @since 3.16.0.\ntype GeneralClientCapabilities struct {\n\t// RegularExpressions is the client capabilities specific to regular expressions.\n\t//\n\t// @since 3.16.0.\n\tRegularExpressions *RegularExpressionsClientCapabilities `json:\"regularExpressions,omitempty\"`\n\n\t// Markdown client capabilities specific to the client's markdown parser.\n\t//\n\t// @since 3.16.0.\n\tMarkdown *MarkdownClientCapabilities `json:\"markdown,omitempty\"`\n}\n\n// RegularExpressionsClientCapabilities represents a client capabilities specific to regular expressions.\n//\n// The following features from the ECMAScript 2020 regular expression specification are NOT mandatory for a client:\n//\n//\tAssertions\n//\n// Lookahead assertion, Negative lookahead assertion, lookbehind assertion, negative lookbehind assertion.\n//\n//\tCharacter classes\n//\n// Matching control characters using caret notation (e.g. \"\\cX\") and matching UTF-16 code units (e.g. \"\\uhhhh\").\n//\n//\tGroup and ranges\n//\n// Named capturing groups.\n//\n//\tUnicode property escapes\n//\n// None of the features needs to be supported.\n//\n// The only regular expression flag that a client needs to support is \"i\" to specify a case insensitive search.\n//\n// @since 3.16.0.\ntype RegularExpressionsClientCapabilities struct {\n\t// Engine is the engine's name.\n\t//\n\t// Well known engine name is \"ECMAScript\".\n\t//  https://tc39.es/ecma262/#sec-regexp-regular-expression-objects\n\t//  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n\tEngine string `json:\"engine\"`\n\n\t// Version is the engine's version.\n\t//\n\t// Well known engine version is \"ES2020\".\n\t//  https://tc39.es/ecma262/#sec-regexp-regular-expression-objects\n\t//  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n\tVersion string `json:\"version,omitempty\"`\n}\n\n// MarkdownClientCapabilities represents a client capabilities specific to the used markdown parser.\n//\n// @since 3.16.0.\ntype MarkdownClientCapabilities struct {\n\t// Parser is the name of the parser.\n\tParser string `json:\"parser\"`\n\n\t// version is the version of the parser.\n\tVersion string `json:\"version,omitempty\"`\n}\n"
  },
  {
    "path": "lsp/protocol/capabilities_client_test.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"workspace\":{\"applyEdit\":true,\"workspaceEdit\":{\"documentChanges\":true,\"failureHandling\":\"FailureHandling\",\"resourceOperations\":[\"ResourceOperations\"]},\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true,\"symbolKind\":{\"valueSet\":[1,2,3,4,5,6]}},\"executeCommand\":{\"dynamicRegistration\":true},\"workspaceFolders\":true,\"configuration\":true},\"textDocument\":{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true,\"commitCharactersSupport\":true,\"documentationFormat\":[\"plaintext\",\"markdown\"],\"deprecatedSupport\":true,\"preselectSupport\":true},\"completionItemKind\":{\"valueSet\":[1]},\"contextSupport\":true},\"hover\":{\"dynamicRegistration\":true,\"contentFormat\":[\"plaintext\",\"markdown\"]},\"signatureHelp\":{\"dynamicRegistration\":true,\"signatureInformation\":{\"documentationFormat\":[\"plaintext\",\"markdown\"]}},\"declaration\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"definition\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"typeDefinition\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"implementation\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true,\"symbolKind\":{\"valueSet\":[1,2,3,4,5,6]},\"hierarchicalDocumentSymbolSupport\":true},\"codeAction\":{\"dynamicRegistration\":true,\"codeActionLiteralSupport\":{\"codeActionKind\":{\"valueSet\":[\"quickfix\",\"refactor\",\"refactor.extract\",\"refactor.rewrite\",\"source\",\"source.organizeImports\"]}}},\"codeLens\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true},\"colorProvider\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"publishDiagnostics\":{\"relatedInformation\":true},\"rename\":{\"dynamicRegistration\":true,\"prepareSupport\":true},\"foldingRange\":{\"dynamicRegistration\":true,\"rangeLimit\":5,\"lineFoldingOnly\":true},\"selectionRange\":{\"dynamicRegistration\":true},\"callHierarchy\":{\"dynamicRegistration\":true},\"semanticTokens\":{\"dynamicRegistration\":true,\"requests\":{\"range\":true,\"full\":true},\"tokenTypes\":[\"test\",\"tokenTypes\"],\"tokenModifiers\":[\"test\",\"tokenModifiers\"],\"formats\":[\"relative\"],\"overlappingTokenSupport\":true,\"multilineTokenSupport\":true},\"linkedEditingRange\":{\"dynamicRegistration\":true},\"moniker\":{\"dynamicRegistration\":true}},\"window\":{\"workDoneProgress\":true,\"showMessage\":{\"messageActionItem\":{\"additionalPropertiesSupport\":true}},\"showDocument\":{\"support\":true}},\"general\":{\"regularExpressions\":{\"engine\":\"ECMAScript\",\"version\":\"ES2020\"},\"markdown\":{\"parser\":\"marked\",\"version\":\"1.1.0\"}},\"experimental\":\"testExperimental\"}`\n\t\twantNil = `{}`\n\t)\n\twantType := ClientCapabilities{\n\t\tWorkspace: &WorkspaceClientCapabilities{\n\t\t\tApplyEdit: true,\n\t\t\tWorkspaceEdit: &WorkspaceClientCapabilitiesWorkspaceEdit{\n\t\t\t\tDocumentChanges:    true,\n\t\t\t\tFailureHandling:    \"FailureHandling\",\n\t\t\t\tResourceOperations: []string{\"ResourceOperations\"},\n\t\t\t},\n\t\t\tDidChangeConfiguration: &DidChangeConfigurationWorkspaceClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tDidChangeWatchedFiles: &DidChangeWatchedFilesWorkspaceClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tSymbol: &WorkspaceSymbolClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tSymbolKind: &SymbolKindCapabilities{\n\t\t\t\t\tValueSet: []SymbolKind{\n\t\t\t\t\t\tSymbolKindFile,\n\t\t\t\t\t\tSymbolKindModule,\n\t\t\t\t\t\tSymbolKindNamespace,\n\t\t\t\t\t\tSymbolKindPackage,\n\t\t\t\t\t\tSymbolKindClass,\n\t\t\t\t\t\tSymbolKindMethod,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tExecuteCommand: &ExecuteCommandClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tWorkspaceFolders: true,\n\t\t\tConfiguration:    true,\n\t\t},\n\t\tTextDocument: &TextDocumentClientCapabilities{\n\t\t\tSynchronization: &TextDocumentSyncClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tWillSave:            true,\n\t\t\t\tWillSaveWaitUntil:   true,\n\t\t\t\tDidSave:             true,\n\t\t\t},\n\t\t\tCompletion: &CompletionTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tCompletionItem: &CompletionTextDocumentClientCapabilitiesItem{\n\t\t\t\t\tSnippetSupport:          true,\n\t\t\t\t\tCommitCharactersSupport: true,\n\t\t\t\t\tDocumentationFormat: []MarkupKind{\n\t\t\t\t\t\tPlainText,\n\t\t\t\t\t\tMarkdown,\n\t\t\t\t\t},\n\t\t\t\t\tDeprecatedSupport: true,\n\t\t\t\t\tPreselectSupport:  true,\n\t\t\t\t},\n\t\t\t\tCompletionItemKind: &CompletionTextDocumentClientCapabilitiesItemKind{\n\t\t\t\t\tValueSet: []CompletionItemKind{CompletionItemKindText},\n\t\t\t\t},\n\t\t\t\tContextSupport: true,\n\t\t\t},\n\t\t\tHover: &HoverTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tContentFormat: []MarkupKind{\n\t\t\t\t\tPlainText,\n\t\t\t\t\tMarkdown,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSignatureHelp: &SignatureHelpTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tSignatureInformation: &TextDocumentClientCapabilitiesSignatureInformation{\n\t\t\t\t\tDocumentationFormat: []MarkupKind{\n\t\t\t\t\t\tPlainText,\n\t\t\t\t\t\tMarkdown,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tDeclaration: &DeclarationTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tLinkSupport:         true,\n\t\t\t},\n\t\t\tDefinition: &DefinitionTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tLinkSupport:         true,\n\t\t\t},\n\t\t\tTypeDefinition: &TypeDefinitionTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tLinkSupport:         true,\n\t\t\t},\n\t\t\tImplementation: &ImplementationTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tLinkSupport:         true,\n\t\t\t},\n\t\t\tReferences: &ReferencesTextDocumentClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tDocumentHighlight: &DocumentHighlightClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tDocumentSymbol: &DocumentSymbolClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tSymbolKind: &SymbolKindCapabilities{\n\t\t\t\t\tValueSet: []SymbolKind{\n\t\t\t\t\t\tSymbolKindFile,\n\t\t\t\t\t\tSymbolKindModule,\n\t\t\t\t\t\tSymbolKindNamespace,\n\t\t\t\t\t\tSymbolKindPackage,\n\t\t\t\t\t\tSymbolKindClass,\n\t\t\t\t\t\tSymbolKindMethod,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tHierarchicalDocumentSymbolSupport: true,\n\t\t\t},\n\t\t\tCodeAction: &CodeActionClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tCodeActionLiteralSupport: &CodeActionClientCapabilitiesLiteralSupport{\n\t\t\t\t\tCodeActionKind: &CodeActionClientCapabilitiesKind{\n\t\t\t\t\t\tValueSet: []CodeActionKind{\n\t\t\t\t\t\t\tQuickFix,\n\t\t\t\t\t\t\tRefactor,\n\t\t\t\t\t\t\tRefactorExtract,\n\t\t\t\t\t\t\tRefactorRewrite,\n\t\t\t\t\t\t\tSource,\n\t\t\t\t\t\t\tSourceOrganizeImports,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tCodeLens: &CodeLensClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tDocumentLink: &DocumentLinkClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tColorProvider: &DocumentColorClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tFormatting: &DocumentFormattingClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tRangeFormatting: &DocumentRangeFormattingClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tOnTypeFormatting: &DocumentOnTypeFormattingClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tPublishDiagnostics: &PublishDiagnosticsClientCapabilities{\n\t\t\t\tRelatedInformation: true,\n\t\t\t},\n\t\t\tRename: &RenameClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tPrepareSupport:      true,\n\t\t\t},\n\t\t\tFoldingRange: &FoldingRangeClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tRangeLimit:          uint32(5),\n\t\t\t\tLineFoldingOnly:     true,\n\t\t\t},\n\t\t\tSelectionRange: &SelectionRangeClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tCallHierarchy: &CallHierarchyClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tSemanticTokens: &SemanticTokensClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t\tRequests: SemanticTokensWorkspaceClientCapabilitiesRequests{\n\t\t\t\t\tRange: true,\n\t\t\t\t\tFull:  true,\n\t\t\t\t},\n\t\t\t\tTokenTypes:     []string{\"test\", \"tokenTypes\"},\n\t\t\t\tTokenModifiers: []string{\"test\", \"tokenModifiers\"},\n\t\t\t\tFormats: []TokenFormat{\n\t\t\t\t\tTokenFormatRelative,\n\t\t\t\t},\n\t\t\t\tOverlappingTokenSupport: true,\n\t\t\t\tMultilineTokenSupport:   true,\n\t\t\t},\n\t\t\tLinkedEditingRange: &LinkedEditingRangeClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t\tMoniker: &MonikerClientCapabilities{\n\t\t\t\tDynamicRegistration: true,\n\t\t\t},\n\t\t},\n\t\tWindow: &WindowClientCapabilities{\n\t\t\tWorkDoneProgress: true,\n\t\t\tShowMessage: &ShowMessageRequestClientCapabilities{\n\t\t\t\tMessageActionItem: &ShowMessageRequestClientCapabilitiesMessageActionItem{\n\t\t\t\t\tAdditionalPropertiesSupport: true,\n\t\t\t\t},\n\t\t\t},\n\t\t\tShowDocument: &ShowDocumentClientCapabilities{\n\t\t\t\tSupport: true,\n\t\t\t},\n\t\t},\n\t\tGeneral: &GeneralClientCapabilities{\n\t\t\tRegularExpressions: &RegularExpressionsClientCapabilities{\n\t\t\t\tEngine:  \"ECMAScript\",\n\t\t\t\tVersion: \"ES2020\",\n\t\t\t},\n\t\t\tMarkdown: &MarkdownClientCapabilities{\n\t\t\t\tParser:  \"marked\",\n\t\t\t\tVersion: \"1.1.0\",\n\t\t\t},\n\t\t},\n\t\tExperimental: \"testExperimental\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          ClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             ClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkspaceClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst want = `{\"applyEdit\":true,\"workspaceEdit\":{\"documentChanges\":true,\"failureHandling\":\"FailureHandling\",\"resourceOperations\":[\"ResourceOperations\"],\"normalizesLineEndings\":true,\"changeAnnotationSupport\":{\"groupsOnLabel\":true}},\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true,\"symbolKind\":{\"valueSet\":[1,2,3,4,5,6]}},\"executeCommand\":{\"dynamicRegistration\":true},\"workspaceFolders\":true,\"configuration\":true,\"semanticTokens\":{\"refreshSupport\":true},\"codeLens\":{\"refreshSupport\":true},\"fileOperations\":{\"dynamicRegistration\":true,\"didCreate\":true,\"willCreate\":true,\"didRename\":true,\"willRename\":true,\"didDelete\":true,\"willDelete\":true}}`\n\twantType := WorkspaceClientCapabilities{\n\t\tApplyEdit: true,\n\t\tWorkspaceEdit: &WorkspaceClientCapabilitiesWorkspaceEdit{\n\t\t\tDocumentChanges:       true,\n\t\t\tFailureHandling:       \"FailureHandling\",\n\t\t\tResourceOperations:    []string{\"ResourceOperations\"},\n\t\t\tNormalizesLineEndings: true,\n\t\t\tChangeAnnotationSupport: &WorkspaceClientCapabilitiesWorkspaceEditChangeAnnotationSupport{\n\t\t\t\tGroupsOnLabel: true,\n\t\t\t},\n\t\t},\n\t\tDidChangeConfiguration: &DidChangeConfigurationWorkspaceClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tDidChangeWatchedFiles: &DidChangeWatchedFilesWorkspaceClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tSymbol: &WorkspaceSymbolClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tSymbolKind: &SymbolKindCapabilities{\n\t\t\t\tValueSet: []SymbolKind{\n\t\t\t\t\tSymbolKindFile,\n\t\t\t\t\tSymbolKindModule,\n\t\t\t\t\tSymbolKindNamespace,\n\t\t\t\t\tSymbolKindPackage,\n\t\t\t\t\tSymbolKindClass,\n\t\t\t\t\tSymbolKindMethod,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tExecuteCommand: &ExecuteCommandClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tWorkspaceFolders: true,\n\t\tConfiguration:    true,\n\t\tSemanticTokens: &SemanticTokensWorkspaceClientCapabilities{\n\t\t\tRefreshSupport: true,\n\t\t},\n\t\tCodeLens: &CodeLensWorkspaceClientCapabilities{\n\t\t\tRefreshSupport: true,\n\t\t},\n\t\tFileOperations: &WorkspaceClientCapabilitiesFileOperations{\n\t\t\tDynamicRegistration: true,\n\t\t\tDidCreate:           true,\n\t\t\tWillCreate:          true,\n\t\t\tDidRename:           true,\n\t\t\tWillRename:          true,\n\t\t\tDidDelete:           true,\n\t\t\tWillDelete:          true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkspaceClientCapabilitiesWorkspaceEdit(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"documentChanges\":true,\"failureHandling\":\"abort\",\"resourceOperations\":[\"create\"],\"normalizesLineEndings\":true,\"changeAnnotationSupport\":{\"groupsOnLabel\":true}}`\n\t\twantNil = `{}`\n\t)\n\twantType := WorkspaceClientCapabilitiesWorkspaceEdit{\n\t\tDocumentChanges: true,\n\t\tFailureHandling: string(FailureHandlingKindAbort),\n\t\tResourceOperations: []string{\n\t\t\t\"create\",\n\t\t},\n\t\tNormalizesLineEndings: true,\n\t\tChangeAnnotationSupport: &WorkspaceClientCapabilitiesWorkspaceEditChangeAnnotationSupport{\n\t\t\tGroupsOnLabel: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceClientCapabilitiesWorkspaceEdit\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          WorkspaceClientCapabilitiesWorkspaceEdit{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceClientCapabilitiesWorkspaceEdit\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             WorkspaceClientCapabilitiesWorkspaceEdit{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceClientCapabilitiesWorkspaceEdit\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true,\"commitCharactersSupport\":true,\"documentationFormat\":[\"plaintext\",\"markdown\"],\"deprecatedSupport\":true,\"preselectSupport\":true},\"completionItemKind\":{\"valueSet\":[1]},\"contextSupport\":true},\"hover\":{\"dynamicRegistration\":true,\"contentFormat\":[\"plaintext\",\"markdown\"]},\"signatureHelp\":{\"dynamicRegistration\":true,\"signatureInformation\":{\"documentationFormat\":[\"plaintext\",\"markdown\"]}},\"declaration\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"definition\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"typeDefinition\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"implementation\":{\"dynamicRegistration\":true,\"linkSupport\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true,\"symbolKind\":{\"valueSet\":[1,2,3,4,5,6]},\"hierarchicalDocumentSymbolSupport\":true},\"codeAction\":{\"dynamicRegistration\":true,\"codeActionLiteralSupport\":{\"codeActionKind\":{\"valueSet\":[\"quickfix\",\"refactor\",\"refactor.extract\",\"refactor.rewrite\",\"source\",\"source.organizeImports\"]}}},\"codeLens\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true},\"colorProvider\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"publishDiagnostics\":{\"relatedInformation\":true},\"rename\":{\"dynamicRegistration\":true,\"prepareSupport\":true},\"foldingRange\":{\"dynamicRegistration\":true,\"rangeLimit\":5,\"lineFoldingOnly\":true},\"selectionRange\":{\"dynamicRegistration\":true},\"callHierarchy\":{\"dynamicRegistration\":true},\"semanticTokens\":{\"dynamicRegistration\":true,\"requests\":{\"range\":true,\"full\":true},\"tokenTypes\":[\"test\",\"tokenTypes\"],\"tokenModifiers\":[\"test\",\"tokenModifiers\"],\"formats\":[\"relative\"],\"overlappingTokenSupport\":true,\"multilineTokenSupport\":true},\"linkedEditingRange\":{\"dynamicRegistration\":true},\"moniker\":{\"dynamicRegistration\":true}}`\n\t\twantNil = `{}`\n\t)\n\twantType := TextDocumentClientCapabilities{\n\t\tSynchronization: &TextDocumentSyncClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tWillSave:            true,\n\t\t\tWillSaveWaitUntil:   true,\n\t\t\tDidSave:             true,\n\t\t},\n\t\tCompletion: &CompletionTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tCompletionItem: &CompletionTextDocumentClientCapabilitiesItem{\n\t\t\t\tSnippetSupport:          true,\n\t\t\t\tCommitCharactersSupport: true,\n\t\t\t\tDocumentationFormat: []MarkupKind{\n\t\t\t\t\tPlainText,\n\t\t\t\t\tMarkdown,\n\t\t\t\t},\n\t\t\t\tDeprecatedSupport: true,\n\t\t\t\tPreselectSupport:  true,\n\t\t\t},\n\t\t\tCompletionItemKind: &CompletionTextDocumentClientCapabilitiesItemKind{\n\t\t\t\tValueSet: []CompletionItemKind{CompletionItemKindText},\n\t\t\t},\n\t\t\tContextSupport: true,\n\t\t},\n\t\tHover: &HoverTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tContentFormat: []MarkupKind{\n\t\t\t\tPlainText,\n\t\t\t\tMarkdown,\n\t\t\t},\n\t\t},\n\t\tSignatureHelp: &SignatureHelpTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tSignatureInformation: &TextDocumentClientCapabilitiesSignatureInformation{\n\t\t\t\tDocumentationFormat: []MarkupKind{\n\t\t\t\t\tPlainText,\n\t\t\t\t\tMarkdown,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tDeclaration: &DeclarationTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tLinkSupport:         true,\n\t\t},\n\t\tDefinition: &DefinitionTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tLinkSupport:         true,\n\t\t},\n\t\tTypeDefinition: &TypeDefinitionTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tLinkSupport:         true,\n\t\t},\n\t\tImplementation: &ImplementationTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tLinkSupport:         true,\n\t\t},\n\t\tReferences: &ReferencesTextDocumentClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tDocumentHighlight: &DocumentHighlightClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tDocumentSymbol: &DocumentSymbolClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tSymbolKind: &SymbolKindCapabilities{\n\t\t\t\tValueSet: []SymbolKind{\n\t\t\t\t\tSymbolKindFile,\n\t\t\t\t\tSymbolKindModule,\n\t\t\t\t\tSymbolKindNamespace,\n\t\t\t\t\tSymbolKindPackage,\n\t\t\t\t\tSymbolKindClass,\n\t\t\t\t\tSymbolKindMethod,\n\t\t\t\t},\n\t\t\t},\n\t\t\tHierarchicalDocumentSymbolSupport: true,\n\t\t},\n\t\tCodeAction: &CodeActionClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tCodeActionLiteralSupport: &CodeActionClientCapabilitiesLiteralSupport{\n\t\t\t\tCodeActionKind: &CodeActionClientCapabilitiesKind{\n\t\t\t\t\tValueSet: []CodeActionKind{\n\t\t\t\t\t\tQuickFix,\n\t\t\t\t\t\tRefactor,\n\t\t\t\t\t\tRefactorExtract,\n\t\t\t\t\t\tRefactorRewrite,\n\t\t\t\t\t\tSource,\n\t\t\t\t\t\tSourceOrganizeImports,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tCodeLens: &CodeLensClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tDocumentLink: &DocumentLinkClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tColorProvider: &DocumentColorClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tFormatting: &DocumentFormattingClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tRangeFormatting: &DocumentRangeFormattingClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tOnTypeFormatting: &DocumentOnTypeFormattingClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tPublishDiagnostics: &PublishDiagnosticsClientCapabilities{\n\t\t\tRelatedInformation: true,\n\t\t},\n\t\tRename: &RenameClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tPrepareSupport:      true,\n\t\t},\n\t\tFoldingRange: &FoldingRangeClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tRangeLimit:          uint32(5),\n\t\t\tLineFoldingOnly:     true,\n\t\t},\n\t\tSelectionRange: &SelectionRangeClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tCallHierarchy: &CallHierarchyClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tSemanticTokens: &SemanticTokensClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t\tRequests: SemanticTokensWorkspaceClientCapabilitiesRequests{\n\t\t\t\tRange: true,\n\t\t\t\tFull:  true,\n\t\t\t},\n\t\t\tTokenTypes:     []string{\"test\", \"tokenTypes\"},\n\t\t\tTokenModifiers: []string{\"test\", \"tokenModifiers\"},\n\t\t\tFormats: []TokenFormat{\n\t\t\t\tTokenFormatRelative,\n\t\t\t},\n\t\t\tOverlappingTokenSupport: true,\n\t\t\tMultilineTokenSupport:   true,\n\t\t},\n\t\tLinkedEditingRange: &LinkedEditingRangeClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t\tMoniker: &MonikerClientCapabilities{\n\t\t\tDynamicRegistration: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          TextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             TextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentSyncClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := TextDocumentSyncClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tWillSave:            true,\n\t\tWillSaveWaitUntil:   true,\n\t\tDidSave:             true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentSyncClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          TextDocumentSyncClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentSyncClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             TextDocumentSyncClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentSyncClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCompletionTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true,\"commitCharactersSupport\":true,\"documentationFormat\":[\"plaintext\",\"markdown\"],\"deprecatedSupport\":true,\"preselectSupport\":true,\"tagSupport\":{\"valueSet\":[1]},\"insertReplaceSupport\":true,\"resolveSupport\":{\"properties\":[\"test\",\"properties\"]},\"insertTextModeSupport\":{\"valueSet\":[1,2]}},\"completionItemKind\":{\"valueSet\":[1]},\"contextSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := CompletionTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tCompletionItem: &CompletionTextDocumentClientCapabilitiesItem{\n\t\t\tSnippetSupport:          true,\n\t\t\tCommitCharactersSupport: true,\n\t\t\tDocumentationFormat: []MarkupKind{\n\t\t\t\tPlainText,\n\t\t\t\tMarkdown,\n\t\t\t},\n\t\t\tDeprecatedSupport: true,\n\t\t\tPreselectSupport:  true,\n\t\t\tTagSupport: &CompletionTextDocumentClientCapabilitiesItemTagSupport{\n\t\t\t\tValueSet: []CompletionItemTag{\n\t\t\t\t\tCompletionItemTagDeprecated,\n\t\t\t\t},\n\t\t\t},\n\t\t\tInsertReplaceSupport: true,\n\t\t\tResolveSupport: &CompletionTextDocumentClientCapabilitiesItemResolveSupport{\n\t\t\t\tProperties: []string{\"test\", \"properties\"},\n\t\t\t},\n\t\t\tInsertTextModeSupport: &CompletionTextDocumentClientCapabilitiesItemInsertTextModeSupport{\n\t\t\t\tValueSet: []InsertTextMode{\n\t\t\t\t\tInsertTextModeAsIs,\n\t\t\t\t\tInsertTextModeAdjustIndentation,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tCompletionItemKind: &CompletionTextDocumentClientCapabilitiesItemKind{\n\t\t\tValueSet: []CompletionItemKind{CompletionItemKindText},\n\t\t},\n\t\tContextSupport: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CompletionTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          CompletionTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CompletionTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             CompletionTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CompletionTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestHoverTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"contentFormat\":[\"plaintext\",\"markdown\"]}`\n\t\twantNil = `{}`\n\t)\n\twantType := HoverTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tContentFormat: []MarkupKind{\n\t\t\tPlainText,\n\t\t\tMarkdown,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          HoverTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          HoverTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             HoverTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             HoverTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got HoverTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSignatureHelpTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"signatureInformation\":{\"documentationFormat\":[\"plaintext\",\"markdown\"],\"parameterInformation\":{\"labelOffsetSupport\":true},\"activeParameterSupport\":true},\"contextSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := SignatureHelpTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tSignatureInformation: &TextDocumentClientCapabilitiesSignatureInformation{\n\t\t\tDocumentationFormat: []MarkupKind{\n\t\t\t\tPlainText,\n\t\t\t\tMarkdown,\n\t\t\t},\n\t\t\tParameterInformation: &TextDocumentClientCapabilitiesParameterInformation{\n\t\t\t\tLabelOffsetSupport: true,\n\t\t\t},\n\t\t\tActiveParameterSupport: true,\n\t\t},\n\t\tContextSupport: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SignatureHelpTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          SignatureHelpTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SignatureHelpTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             SignatureHelpTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SignatureHelpTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDeclarationTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"linkSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := DeclarationTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tLinkSupport:         true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DeclarationTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DeclarationTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DeclarationTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DeclarationTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DeclarationTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDefinitionTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"linkSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := DefinitionTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tLinkSupport:         true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DefinitionTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DefinitionTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DefinitionTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DefinitionTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DefinitionTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTypeDefinitionTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"linkSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := TypeDefinitionTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tLinkSupport:         true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TypeDefinitionTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          TypeDefinitionTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TypeDefinitionTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             TypeDefinitionTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TypeDefinitionTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestImplementationTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"linkSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := ImplementationTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tLinkSupport:         true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ImplementationTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          ImplementationTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ImplementationTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             ImplementationTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ImplementationTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestReferencesTextDocumentClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := ReferencesTextDocumentClientCapabilities{\n\t\tDynamicRegistration: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ReferencesTextDocumentClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          ReferencesTextDocumentClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ReferencesTextDocumentClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             ReferencesTextDocumentClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ReferencesTextDocumentClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentHighlightClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := DocumentHighlightClientCapabilities{\n\t\tDynamicRegistration: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentHighlightClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentHighlightClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentHighlightClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentHighlightClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentHighlightClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentSymbolClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"symbolKind\":{\"valueSet\":[1,2,3,4,5,6]},\"hierarchicalDocumentSymbolSupport\":true,\"tagSupport\":{\"valueSet\":[1]},\"labelSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := DocumentSymbolClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tSymbolKind: &SymbolKindCapabilities{\n\t\t\tValueSet: []SymbolKind{\n\t\t\t\tSymbolKindFile,\n\t\t\t\tSymbolKindModule,\n\t\t\t\tSymbolKindNamespace,\n\t\t\t\tSymbolKindPackage,\n\t\t\t\tSymbolKindClass,\n\t\t\t\tSymbolKindMethod,\n\t\t\t},\n\t\t},\n\t\tHierarchicalDocumentSymbolSupport: true,\n\t\tTagSupport: &DocumentSymbolClientCapabilitiesTagSupport{\n\t\t\tValueSet: []SymbolTag{\n\t\t\t\tSymbolTagDeprecated,\n\t\t\t},\n\t\t},\n\t\tLabelSupport: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentSymbolClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentSymbolClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentSymbolClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentSymbolClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentSymbolClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeActionClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"codeActionLiteralSupport\":{\"codeActionKind\":{\"valueSet\":[\"quickfix\",\"refactor\",\"refactor.extract\",\"refactor.rewrite\",\"source\",\"source.organizeImports\"]}},\"isPreferredSupport\":true,\"disabledSupport\":true,\"dataSupport\":true,\"resolveSupport\":{\"properties\":[\"testProperties\"]},\"honorsChangeAnnotations\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := CodeActionClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tCodeActionLiteralSupport: &CodeActionClientCapabilitiesLiteralSupport{\n\t\t\tCodeActionKind: &CodeActionClientCapabilitiesKind{\n\t\t\t\tValueSet: []CodeActionKind{\n\t\t\t\t\tQuickFix,\n\t\t\t\t\tRefactor,\n\t\t\t\t\tRefactorExtract,\n\t\t\t\t\tRefactorRewrite,\n\t\t\t\t\tSource,\n\t\t\t\t\tSourceOrganizeImports,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tIsPreferredSupport: true,\n\t\tDisabledSupport:    true,\n\t\tDataSupport:        true,\n\t\tResolveSupport: &CodeActionClientCapabilitiesResolveSupport{\n\t\t\tProperties: []string{\"testProperties\"},\n\t\t},\n\t\tHonorsChangeAnnotations: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeActionClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          CodeActionClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeActionClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             CodeActionClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeActionClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeLensClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := CodeLensClientCapabilities{\n\t\tDynamicRegistration: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeLensClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          CodeLensClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeLensClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             CodeLensClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeLensClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentLinkClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"tooltipSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := DocumentLinkClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tTooltipSupport:      true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentLinkClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentLinkClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentLinkClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentLinkClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentLinkClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentColorClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := DocumentColorClientCapabilities{\n\t\tDynamicRegistration: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentColorClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentColorClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentColorClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentColorClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentColorClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestPublishDiagnosticsClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"relatedInformation\":true,\"tagSupport\":{\"valueSet\":[2,1]},\"versionSupport\":true,\"codeDescriptionSupport\":true,\"dataSupport\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := PublishDiagnosticsClientCapabilities{\n\t\tRelatedInformation: true,\n\t\tTagSupport: &PublishDiagnosticsClientCapabilitiesTagSupport{\n\t\t\tValueSet: []DiagnosticTag{\n\t\t\t\tDiagnosticTagDeprecated,\n\t\t\t\tDiagnosticTagUnnecessary,\n\t\t\t},\n\t\t},\n\t\tVersionSupport:         true,\n\t\tCodeDescriptionSupport: true,\n\t\tDataSupport:            true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          PublishDiagnosticsClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          PublishDiagnosticsClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             PublishDiagnosticsClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             PublishDiagnosticsClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got PublishDiagnosticsClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRenameClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"prepareSupport\":true,\"prepareSupportDefaultBehavior\":1,\"honorsChangeAnnotations\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := RenameClientCapabilities{\n\t\tDynamicRegistration:           true,\n\t\tPrepareSupport:                true,\n\t\tPrepareSupportDefaultBehavior: PrepareSupportDefaultBehaviorIdentifier,\n\t\tHonorsChangeAnnotations:       true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RenameClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          RenameClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RenameClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             RenameClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RenameClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestFoldingRangeClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"rangeLimit\":5,\"lineFoldingOnly\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := FoldingRangeClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tRangeLimit:          uint32(5),\n\t\tLineFoldingOnly:     true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          FoldingRangeClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          FoldingRangeClientCapabilities{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             FoldingRangeClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             FoldingRangeClientCapabilities{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got FoldingRangeClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSemanticTokensClientCapabilities(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"dynamicRegistration\":true,\"requests\":{\"range\":true,\"full\":true},\"tokenTypes\":[\"namespace\",\"type\",\"class\"],\"tokenModifiers\":[\"declaration\",\"definition\",\"readonly\"],\"formats\":[\"relative\"],\"overlappingTokenSupport\":true,\"multilineTokenSupport\":true}`\n\t\twantNil = `{\"requests\":{},\"tokenTypes\":[\"namespace\",\"type\",\"class\"],\"tokenModifiers\":[\"declaration\",\"definition\",\"readonly\"],\"formats\":[\"relative\"]}`\n\t)\n\twantType := SemanticTokensClientCapabilities{\n\t\tDynamicRegistration: true,\n\t\tRequests: SemanticTokensWorkspaceClientCapabilitiesRequests{\n\t\t\tRange: true,\n\t\t\tFull:  true,\n\t\t},\n\t\tTokenTypes: []string{\n\t\t\tstring(SemanticTokenNamespace),\n\t\t\tstring(SemanticTokenType),\n\t\t\tstring(SemanticTokenClass),\n\t\t},\n\t\tTokenModifiers: []string{\n\t\t\tstring(SemanticTokenModifierDeclaration),\n\t\t\tstring(SemanticTokenModifierDefinition),\n\t\t\tstring(SemanticTokenModifierReadonly),\n\t\t},\n\t\tFormats: []TokenFormat{\n\t\t\tTokenFormatRelative,\n\t\t},\n\t\tOverlappingTokenSupport: true,\n\t\tMultilineTokenSupport:   true,\n\t}\n\twantTypeNil := SemanticTokensClientCapabilities{\n\t\tRequests: SemanticTokensWorkspaceClientCapabilitiesRequests{},\n\t\tTokenTypes: []string{\n\t\t\tstring(SemanticTokenNamespace),\n\t\t\tstring(SemanticTokenType),\n\t\t\tstring(SemanticTokenClass),\n\t\t},\n\t\tTokenModifiers: []string{\n\t\t\tstring(SemanticTokenModifierDeclaration),\n\t\t\tstring(SemanticTokenModifierDefinition),\n\t\t\tstring(SemanticTokenModifierReadonly),\n\t\t},\n\t\tFormats: []TokenFormat{\n\t\t\tTokenFormatRelative,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SemanticTokensClientCapabilities\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SemanticTokensClientCapabilities\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SemanticTokensClientCapabilities\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/capabilities_server.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"strconv\"\n)\n\n// ServerCapabilities efines the capabilities provided by a language server.\ntype ServerCapabilities struct {\n\t// TextDocumentSync defines how text documents are synced. Is either a detailed structure defining each notification\n\t// or for backwards compatibility the TextDocumentSyncKind number.\n\t//\n\t// If omitted it defaults to TextDocumentSyncKind.None`\n\tTextDocumentSync any `json:\"textDocumentSync,omitempty\"` // *TextDocumentSyncOptions | TextDocumentSyncKind\n\n\t// CompletionProvider is The server provides completion support.\n\tCompletionProvider *CompletionOptions `json:\"completionProvider,omitempty\"`\n\n\t// HoverProvider is the server provides hover support.\n\tHoverProvider any `json:\"hoverProvider,omitempty\"` // TODO(zchee): bool | *HoverOptions\n\n\t// SignatureHelpProvider is the server provides signature help support.\n\tSignatureHelpProvider *SignatureHelpOptions `json:\"signatureHelpProvider,omitempty\"`\n\n\t// DeclarationProvider is the server provides Goto Declaration support.\n\t//\n\t// @since 3.14.0.\n\tDeclarationProvider any `json:\"declarationProvider,omitempty\"` // TODO(zchee): bool | *DeclarationOptions | *DeclarationRegistrationOptions\n\n\t// DefinitionProvider is the server provides Goto definition support.\n\tDefinitionProvider any `json:\"definitionProvider,omitempty\"` // TODO(zchee): bool | *DefinitionOptions\n\n\t// TypeDefinitionProvider is the provides Goto Type Definition support.\n\t//\n\t// @since 3.6.0.\n\tTypeDefinitionProvider any `json:\"typeDefinitionProvider,omitempty\"` // TODO(zchee): bool | *TypeDefinitionOptions | *TypeDefinitionRegistrationOptions\n\n\t// ImplementationProvider is the provides Goto Implementation support.\n\t//\n\t// @since 3.6.0.\n\tImplementationProvider any `json:\"implementationProvider,omitempty\"` // TODO(zchee): bool | *ImplementationOptions | *ImplementationRegistrationOptions\n\n\t// ReferencesProvider is the server provides find references support.\n\tReferencesProvider any `json:\"referencesProvider,omitempty\"` // TODO(zchee): bool | *ReferenceOptions\n\n\t// DocumentHighlightProvider is the server provides document highlight support.\n\tDocumentHighlightProvider any `json:\"documentHighlightProvider,omitempty\"` // TODO(zchee): bool | *DocumentHighlightOptions\n\n\t// DocumentSymbolProvider is the server provides document symbol support.\n\tDocumentSymbolProvider any `json:\"documentSymbolProvider,omitempty\"` // TODO(zchee): bool | *DocumentSymbolOptions\n\n\t// CodeActionProvider is the server provides code actions.\n\t//\n\t// CodeActionOptions may only be specified if the client states that it supports CodeActionLiteralSupport in its\n\t// initial Initialize request.\n\tCodeActionProvider any `json:\"codeActionProvider,omitempty\"` // TODO(zchee): bool | *CodeActionOptions\n\n\t// CodeLensProvider is the server provides code lens.\n\tCodeLensProvider *CodeLensOptions `json:\"codeLensProvider,omitempty\"`\n\n\t// The server provides document link support.\n\tDocumentLinkProvider *DocumentLinkOptions `json:\"documentLinkProvider,omitempty\"`\n\n\t// ColorProvider is the server provides color provider support.\n\t//\n\t// @since 3.6.0.\n\tColorProvider any `json:\"colorProvider,omitempty\"` // TODO(zchee): bool | *DocumentColorOptions | *DocumentColorRegistrationOptions\n\n\t// WorkspaceSymbolProvider is the server provides workspace symbol support.\n\tWorkspaceSymbolProvider any `json:\"workspaceSymbolProvider,omitempty\"` // TODO(zchee): bool | *WorkspaceSymbolOptions\n\n\t// DocumentFormattingProvider is the server provides document formatting.\n\tDocumentFormattingProvider any `json:\"documentFormattingProvider,omitempty\"` // TODO(zchee): bool | *DocumentFormattingOptions\n\n\t// DocumentRangeFormattingProvider is the server provides document range formatting.\n\tDocumentRangeFormattingProvider any `json:\"documentRangeFormattingProvider,omitempty\"` // TODO(zchee): bool | *DocumentRangeFormattingOptions\n\n\t// DocumentOnTypeFormattingProvider is the server provides document formatting on typing.\n\tDocumentOnTypeFormattingProvider *DocumentOnTypeFormattingOptions `json:\"documentOnTypeFormattingProvider,omitempty\"`\n\n\t// RenameProvider is the server provides rename support.\n\t//\n\t// RenameOptions may only be specified if the client states that it supports PrepareSupport in its\n\t// initial Initialize request.\n\tRenameProvider any `json:\"renameProvider,omitempty\"` // TODO(zchee): bool | *RenameOptions\n\n\t// FoldingRangeProvider is the server provides folding provider support.\n\t//\n\t// @since 3.10.0.\n\tFoldingRangeProvider any `json:\"foldingRangeProvider,omitempty\"` // TODO(zchee): bool | *FoldingRangeOptions | *FoldingRangeRegistrationOptions\n\n\t// SelectionRangeProvider is the server provides selection range support.\n\t//\n\t// @since 3.15.0.\n\tSelectionRangeProvider any `json:\"selectionRangeProvider,omitempty\"` // TODO(zchee): bool | *SelectionRangeOptions | *SelectionRangeRegistrationOptions\n\n\t// ExecuteCommandProvider is the server provides execute command support.\n\tExecuteCommandProvider *ExecuteCommandOptions `json:\"executeCommandProvider,omitempty\"`\n\n\t// CallHierarchyProvider is the server provides call hierarchy support.\n\t//\n\t// @since 3.16.0.\n\tCallHierarchyProvider any `json:\"callHierarchyProvider,omitempty\"` // TODO(zchee): bool | *CallHierarchyOptions | *CallHierarchyRegistrationOptions\n\n\t// LinkedEditingRangeProvider is the server provides linked editing range support.\n\t//\n\t// @since 3.16.0.\n\tLinkedEditingRangeProvider any `json:\"linkedEditingRangeProvider,omitempty\"` // TODO(zchee): bool | *LinkedEditingRangeOptions | *LinkedEditingRangeRegistrationOptions\n\n\t// SemanticTokensProvider is the server provides semantic tokens support.\n\t//\n\t// @since 3.16.0.\n\tSemanticTokensProvider any `json:\"semanticTokensProvider,omitempty\"` // TODO(zchee): *SemanticTokensOptions | *SemanticTokensRegistrationOptions\n\n\t// Workspace is the window specific server capabilities.\n\tWorkspace *ServerCapabilitiesWorkspace `json:\"workspace,omitempty\"`\n\n\t// MonikerProvider is the server provides moniker support.\n\t//\n\t// @since 3.16.0.\n\tMonikerProvider any `json:\"monikerProvider,omitempty\"` // TODO(zchee): bool | *MonikerOptions | *MonikerRegistrationOptions\n\n\t// Experimental server capabilities.\n\tExperimental any `json:\"experimental,omitempty\"`\n}\n\n// TextDocumentSyncOptions TextDocumentSync options.\ntype TextDocumentSyncOptions struct {\n\t// OpenClose open and close notifications are sent to the server.\n\tOpenClose bool `json:\"openClose,omitempty\"`\n\n\t// Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full\n\t// and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.\n\tChange TextDocumentSyncKind `json:\"change,omitempty\"`\n\n\t// WillSave notifications are sent to the server.\n\tWillSave bool `json:\"willSave,omitempty\"`\n\n\t// WillSaveWaitUntil will save wait until requests are sent to the server.\n\tWillSaveWaitUntil bool `json:\"willSaveWaitUntil,omitempty\"`\n\n\t// Save notifications are sent to the server.\n\tSave *SaveOptions `json:\"save,omitempty\"`\n}\n\n// SaveOptions save options.\ntype SaveOptions struct {\n\t// IncludeText is the client is supposed to include the content on save.\n\tIncludeText bool `json:\"includeText,omitempty\"`\n}\n\n// TextDocumentSyncKind defines how the host (editor) should sync document changes to the language server.\ntype TextDocumentSyncKind float64\n\nconst (\n\t// TextDocumentSyncKindNone documents should not be synced at all.\n\tTextDocumentSyncKindNone TextDocumentSyncKind = 0\n\n\t// TextDocumentSyncKindFull documents are synced by always sending the full content\n\t// of the document.\n\tTextDocumentSyncKindFull TextDocumentSyncKind = 1\n\n\t// TextDocumentSyncKindIncremental documents are synced by sending the full content on open.\n\t// After that only incremental updates to the document are\n\t// send.\n\tTextDocumentSyncKindIncremental TextDocumentSyncKind = 2\n)\n\n// String implements fmt.Stringer.\nfunc (k TextDocumentSyncKind) String() string {\n\tswitch k {\n\tcase TextDocumentSyncKindNone:\n\t\treturn \"None\"\n\tcase TextDocumentSyncKindFull:\n\t\treturn \"Full\"\n\tcase TextDocumentSyncKindIncremental:\n\t\treturn \"Incremental\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// CompletionOptions Completion options.\ntype CompletionOptions struct {\n\t// The server provides support to resolve additional\n\t// information for a completion item.\n\tResolveProvider bool `json:\"resolveProvider,omitempty\"`\n\n\t// The characters that trigger completion automatically.\n\tTriggerCharacters []string `json:\"triggerCharacters,omitempty\"`\n}\n\n// HoverOptions option of hover provider server capabilities.\ntype HoverOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// SignatureHelpOptions SignatureHelp options.\ntype SignatureHelpOptions struct {\n\t// The characters that trigger signature help\n\t// automatically.\n\tTriggerCharacters []string `json:\"triggerCharacters,omitempty\"`\n\n\t// RetriggerCharacters is the slist of characters that re-trigger signature help.\n\t//\n\t// These trigger characters are only active when signature help is already\n\t// showing.\n\t// All trigger characters are also counted as re-trigger characters.\n\t//\n\t// @since 3.15.0.\n\tRetriggerCharacters []string `json:\"retriggerCharacters,omitempty\"`\n}\n\n// DeclarationOptions registration option of Declaration server capability.\n//\n// @since 3.15.0.\ntype DeclarationOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// DeclarationRegistrationOptions registration option of Declaration server capability.\n//\n// @since 3.15.0.\ntype DeclarationRegistrationOptions struct {\n\tDeclarationOptions\n\tTextDocumentRegistrationOptions\n\tStaticRegistrationOptions\n}\n\n// DefinitionOptions registration option of Definition server capability.\n//\n// @since 3.15.0.\ntype DefinitionOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// TypeDefinitionOptions registration option of TypeDefinition server capability.\n//\n// @since 3.15.0.\ntype TypeDefinitionOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// TypeDefinitionRegistrationOptions registration option of TypeDefinition server capability.\n//\n// @since 3.15.0.\ntype TypeDefinitionRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tTypeDefinitionOptions\n\tStaticRegistrationOptions\n}\n\n// ImplementationOptions registration option of Implementation server capability.\n//\n// @since 3.15.0.\ntype ImplementationOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// ImplementationRegistrationOptions registration option of Implementation server capability.\n//\n// @since 3.15.0.\ntype ImplementationRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tImplementationOptions\n\tStaticRegistrationOptions\n}\n\n// ReferenceOptions registration option of Reference server capability.\ntype ReferenceOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// DocumentHighlightOptions registration option of DocumentHighlight server capability.\n//\n// @since 3.15.0.\ntype DocumentHighlightOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// DocumentSymbolOptions registration option of DocumentSymbol server capability.\n//\n// @since 3.15.0.\ntype DocumentSymbolOptions struct {\n\tWorkDoneProgressOptions\n\n\t// Label a human-readable string that is shown when multiple outlines trees\n\t// are shown for the same document.\n\t//\n\t// @since 3.16.0.\n\tLabel string `json:\"label,omitempty\"`\n}\n\n// CodeActionOptions CodeAction options.\ntype CodeActionOptions struct {\n\t// CodeActionKinds that this server may return.\n\t//\n\t// The list of kinds may be generic, such as \"CodeActionKind.Refactor\", or the server\n\t// may list out every specific kind they provide.\n\tCodeActionKinds []CodeActionKind `json:\"codeActionKinds,omitempty\"`\n\n\t// ResolveProvider is the server provides support to resolve additional\n\t// information for a code action.\n\t//\n\t// @since 3.16.0.\n\tResolveProvider bool `json:\"resolveProvider,omitempty\"`\n}\n\n// CodeLensOptions CodeLens options.\ntype CodeLensOptions struct {\n\t// Code lens has a resolve provider as well.\n\tResolveProvider bool `json:\"resolveProvider,omitempty\"`\n}\n\n// DocumentLinkOptions document link options.\ntype DocumentLinkOptions struct {\n\t// ResolveProvider document links have a resolve provider as well.\n\tResolveProvider bool `json:\"resolveProvider,omitempty\"`\n}\n\n// DocumentColorOptions registration option of DocumentColor server capability.\n//\n// @since 3.15.0.\ntype DocumentColorOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// DocumentColorRegistrationOptions registration option of DocumentColor server capability.\n//\n// @since 3.15.0.\ntype DocumentColorRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tStaticRegistrationOptions\n\tDocumentColorOptions\n}\n\n// WorkspaceSymbolOptions registration option of WorkspaceSymbol server capability.\n//\n// @since 3.15.0.\ntype WorkspaceSymbolOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// DocumentFormattingOptions registration option of DocumentFormatting server capability.\n//\n// @since 3.15.0.\ntype DocumentFormattingOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// DocumentRangeFormattingOptions registration option of DocumentRangeFormatting server capability.\n//\n// @since 3.15.0.\ntype DocumentRangeFormattingOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// DocumentOnTypeFormattingOptions format document on type options.\ntype DocumentOnTypeFormattingOptions struct {\n\t// FirstTriggerCharacter a character on which formatting should be triggered, like \"}\".\n\tFirstTriggerCharacter string `json:\"firstTriggerCharacter\"`\n\n\t// MoreTriggerCharacter more trigger characters.\n\tMoreTriggerCharacter []string `json:\"moreTriggerCharacter,omitempty\"`\n}\n\n// RenameOptions rename options.\ntype RenameOptions struct {\n\t// PrepareProvider renames should be checked and tested before being executed.\n\tPrepareProvider bool `json:\"prepareProvider,omitempty\"`\n}\n\n// FoldingRangeOptions registration option of FoldingRange server capability.\n//\n// @since 3.15.0.\ntype FoldingRangeOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// FoldingRangeRegistrationOptions registration option of FoldingRange server capability.\n//\n// @since 3.15.0.\ntype FoldingRangeRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tFoldingRangeOptions\n\tStaticRegistrationOptions\n}\n\n// ExecuteCommandOptions execute command options.\ntype ExecuteCommandOptions struct {\n\t// Commands is the commands to be executed on the server\n\tCommands []string `json:\"commands\"`\n}\n\n// CallHierarchyOptions option of CallHierarchy.\n//\n// @since 3.16.0.\ntype CallHierarchyOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// CallHierarchyRegistrationOptions registration options of CallHierarchy.\n//\n// @since 3.16.0.\ntype CallHierarchyRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tCallHierarchyOptions\n\tStaticRegistrationOptions\n}\n\n// LinkedEditingRangeOptions option of linked editing range provider server capabilities.\n//\n// @since 3.16.0.\ntype LinkedEditingRangeOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// LinkedEditingRangeRegistrationOptions registration option of linked editing range provider server capabilities.\n//\n// @since 3.16.0.\ntype LinkedEditingRangeRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tLinkedEditingRangeOptions\n\tStaticRegistrationOptions\n}\n\n// SemanticTokensOptions option of semantic tokens provider server capabilities.\n//\n// @since 3.16.0.\ntype SemanticTokensOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// SemanticTokensRegistrationOptions registration option of semantic tokens provider server capabilities.\n//\n// @since 3.16.0.\ntype SemanticTokensRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tSemanticTokensOptions\n\tStaticRegistrationOptions\n}\n\n// ServerCapabilitiesWorkspace specific server capabilities.\ntype ServerCapabilitiesWorkspace struct {\n\t// WorkspaceFolders is the server supports workspace folder.\n\t//\n\t// @since 3.6.0.\n\tWorkspaceFolders *ServerCapabilitiesWorkspaceFolders `json:\"workspaceFolders,omitempty\"`\n\n\t// FileOperations is the server is interested in file notifications/requests.\n\t//\n\t// @since 3.16.0.\n\tFileOperations *ServerCapabilitiesWorkspaceFileOperations `json:\"fileOperations,omitempty\"`\n}\n\n// ServerCapabilitiesWorkspaceFolders is the server supports workspace folder.\n//\n// @since 3.6.0.\ntype ServerCapabilitiesWorkspaceFolders struct {\n\t// Supported is the server has support for workspace folders\n\tSupported bool `json:\"supported,omitempty\"`\n\n\t// ChangeNotifications whether the server wants to receive workspace folder\n\t// change notifications.\n\t//\n\t// If a strings is provided the string is treated as a ID\n\t// under which the notification is registered on the client\n\t// side. The ID can be used to unregister for these events\n\t// using the `client/unregisterCapability` request.\n\tChangeNotifications any `json:\"changeNotifications,omitempty\"` // string | boolean\n}\n\n// ServerCapabilitiesWorkspaceFileOperations is the server is interested in file notifications/requests.\n//\n// @since 3.16.0.\ntype ServerCapabilitiesWorkspaceFileOperations struct {\n\t// DidCreate is the server is interested in receiving didCreateFiles\n\t// notifications.\n\tDidCreate *FileOperationRegistrationOptions `json:\"didCreate,omitempty\"`\n\n\t// WillCreate is the server is interested in receiving willCreateFiles requests.\n\tWillCreate *FileOperationRegistrationOptions `json:\"willCreate,omitempty\"`\n\n\t// DidRename is the server is interested in receiving didRenameFiles\n\t// notifications.\n\tDidRename *FileOperationRegistrationOptions `json:\"didRename,omitempty\"`\n\n\t// WillRename is the server is interested in receiving willRenameFiles requests.\n\tWillRename *FileOperationRegistrationOptions `json:\"willRename,omitempty\"`\n\n\t// DidDelete is the server is interested in receiving didDeleteFiles file\n\t// notifications.\n\tDidDelete *FileOperationRegistrationOptions `json:\"didDelete,omitempty\"`\n\n\t// WillDelete is the server is interested in receiving willDeleteFiles file\n\t// requests.\n\tWillDelete *FileOperationRegistrationOptions `json:\"willDelete,omitempty\"`\n}\n\n// FileOperationRegistrationOptions is the options to register for file operations.\n//\n// @since 3.16.0.\ntype FileOperationRegistrationOptions struct {\n\t// filters is the actual filters.\n\tFilters []FileOperationFilter `json:\"filters\"`\n}\n\n// MonikerOptions option of moniker provider server capabilities.\n//\n// @since 3.16.0.\ntype MonikerOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// MonikerRegistrationOptions registration option of moniker provider server capabilities.\n//\n// @since 3.16.0.\ntype MonikerRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\tMonikerOptions\n}\n"
  },
  {
    "path": "lsp/protocol/client.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\n\t\"encoding/json\"\n\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n\t\"github.com/a-h/templ/lsp/xcontext\"\n)\n\n// ClientDispatcher returns a Client that dispatches LSP requests across the\n// given jsonrpc2 connection.\nfunc ClientDispatcher(conn jsonrpc2.Conn, logger *slog.Logger) Client {\n\treturn &client{\n\t\tConn:   conn,\n\t\tlogger: logger,\n\t}\n}\n\n// ClientHandler handler of LSP client.\nfunc ClientHandler(log *slog.Logger, client Client, handler jsonrpc2.Handler) jsonrpc2.Handler {\n\th := func(ctx context.Context, reply jsonrpc2.Replier, req jsonrpc2.Request) error {\n\t\tif ctx.Err() != nil {\n\t\t\txctx := xcontext.Detach(ctx)\n\n\t\t\treturn reply(xctx, nil, ErrRequestCancelled)\n\t\t}\n\n\t\thandled, err := clientDispatch(ctx, log, client, reply, req)\n\t\tif handled || err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn handler(ctx, reply, req)\n\t}\n\n\treturn h\n}\n\n// clientDispatch implements jsonrpc2.Handler.\n//\n//nolint:funlen,cyclop\nfunc clientDispatch(ctx context.Context, log *slog.Logger, client Client, reply jsonrpc2.Replier, req jsonrpc2.Request) (handled bool, err error) {\n\tif ctx.Err() != nil {\n\t\treturn true, reply(ctx, nil, ErrRequestCancelled)\n\t}\n\n\tdec := json.NewDecoder(bytes.NewReader(req.Params()))\n\n\tswitch req.Method() {\n\tcase MethodProgress: // notification\n\t\tdefer log.Debug(MethodProgress, slog.Any(\"error\", err))\n\n\t\tvar params ProgressParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.Progress(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWorkDoneProgressCreate: // request\n\t\tdefer log.Debug(MethodWorkDoneProgressCreate, slog.Any(\"error\", err))\n\n\t\tvar params WorkDoneProgressCreateParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.WorkDoneProgressCreate(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWindowLogMessage: // notification\n\t\tdefer log.Debug(MethodWindowLogMessage, slog.Any(\"error\", err))\n\n\t\tvar params LogMessageParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.LogMessage(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentPublishDiagnostics: // notification\n\t\tdefer log.Debug(MethodTextDocumentPublishDiagnostics, slog.Any(\"error\", err))\n\n\t\tvar params PublishDiagnosticsParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.PublishDiagnostics(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWindowShowMessage: // notification\n\t\tdefer log.Debug(MethodWindowShowMessage, slog.Any(\"error\", err))\n\n\t\tvar params ShowMessageParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.ShowMessage(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWindowShowMessageRequest: // request\n\t\tdefer log.Debug(MethodWindowShowMessageRequest, slog.Any(\"error\", err))\n\n\t\tvar params ShowMessageRequestParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := client.ShowMessageRequest(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTelemetryEvent: // notification\n\t\tdefer log.Debug(MethodTelemetryEvent, slog.Any(\"error\", err))\n\n\t\tvar params any\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.Telemetry(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodClientRegisterCapability: // request\n\t\tdefer log.Debug(MethodClientRegisterCapability, slog.Any(\"error\", err))\n\n\t\tvar params RegistrationParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.RegisterCapability(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodClientUnregisterCapability: // request\n\t\tdefer log.Debug(MethodClientUnregisterCapability, slog.Any(\"error\", err))\n\n\t\tvar params UnregistrationParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := client.UnregisterCapability(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWorkspaceApplyEdit: // request\n\t\tdefer log.Debug(MethodWorkspaceApplyEdit, slog.Any(\"error\", err))\n\n\t\tvar params ApplyWorkspaceEditParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := client.ApplyEdit(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodWorkspaceConfiguration: // request\n\t\tdefer log.Debug(MethodWorkspaceConfiguration, slog.Any(\"error\", err))\n\n\t\tvar params ConfigurationParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := client.Configuration(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodWorkspaceWorkspaceFolders: // request\n\t\tdefer log.Debug(MethodWorkspaceWorkspaceFolders, slog.Any(\"error\", err))\n\n\t\tif len(req.Params()) > 0 {\n\t\t\treturn true, reply(ctx, nil, fmt.Errorf(\"expected no params: %w\", jsonrpc2.ErrInvalidParams))\n\t\t}\n\n\t\tresp, err := client.WorkspaceFolders(ctx)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tdefault:\n\t\treturn false, nil\n\t}\n}\n\n// Client represents a Language Server Protocol client.\ntype Client interface {\n\tProgress(ctx context.Context, params *ProgressParams) (err error)\n\tWorkDoneProgressCreate(ctx context.Context, params *WorkDoneProgressCreateParams) (err error)\n\tLogMessage(ctx context.Context, params *LogMessageParams) (err error)\n\tPublishDiagnostics(ctx context.Context, params *PublishDiagnosticsParams) (err error)\n\tShowMessage(ctx context.Context, params *ShowMessageParams) (err error)\n\tShowMessageRequest(ctx context.Context, params *ShowMessageRequestParams) (result *MessageActionItem, err error)\n\tTelemetry(ctx context.Context, params any) (err error)\n\tRegisterCapability(ctx context.Context, params *RegistrationParams) (err error)\n\tUnregisterCapability(ctx context.Context, params *UnregistrationParams) (err error)\n\tApplyEdit(ctx context.Context, params *ApplyWorkspaceEditParams) (result *ApplyWorkspaceEditResponse, err error)\n\tConfiguration(ctx context.Context, params *ConfigurationParams) (result []any, err error)\n\tWorkspaceFolders(ctx context.Context) (result []WorkspaceFolder, err error)\n}\n\n// list of client methods.\nconst (\n\t// MethodProgress method name of \"$/progress\".\n\tMethodProgress = \"$/progress\"\n\n\t// MethodWorkDoneProgressCreate method name of \"window/workDoneProgress/create\".\n\tMethodWorkDoneProgressCreate = \"window/workDoneProgress/create\"\n\n\t// MethodWindowShowMessage method name of \"window/showMessage\".\n\tMethodWindowShowMessage = \"window/showMessage\"\n\n\t// MethodWindowShowMessageRequest method name of \"window/showMessageRequest.\n\tMethodWindowShowMessageRequest = \"window/showMessageRequest\"\n\n\t// MethodWindowLogMessage method name of \"window/logMessage.\n\tMethodWindowLogMessage = \"window/logMessage\"\n\n\t// MethodTelemetryEvent method name of \"telemetry/event.\n\tMethodTelemetryEvent = \"telemetry/event\"\n\n\t// MethodClientRegisterCapability method name of \"client/registerCapability.\n\tMethodClientRegisterCapability = \"client/registerCapability\"\n\n\t// MethodClientUnregisterCapability method name of \"client/unregisterCapability.\n\tMethodClientUnregisterCapability = \"client/unregisterCapability\"\n\n\t// MethodTextDocumentPublishDiagnostics method name of \"textDocument/publishDiagnostics.\n\tMethodTextDocumentPublishDiagnostics = \"textDocument/publishDiagnostics\"\n\n\t// MethodWorkspaceApplyEdit method name of \"workspace/applyEdit.\n\tMethodWorkspaceApplyEdit = \"workspace/applyEdit\"\n\n\t// MethodWorkspaceConfiguration method name of \"workspace/configuration.\n\tMethodWorkspaceConfiguration = \"workspace/configuration\"\n\n\t// MethodWorkspaceWorkspaceFolders method name of \"workspace/workspaceFolders\".\n\tMethodWorkspaceWorkspaceFolders = \"workspace/workspaceFolders\"\n)\n\n// client implements a Language Server Protocol client.\ntype client struct {\n\tjsonrpc2.Conn\n\n\tlogger *slog.Logger\n}\n\n// compiler time check whether the Client implements ClientInterface interface.\nvar _ Client = (*client)(nil)\n\n// Progress is the base protocol offers also support to report progress in a generic fashion.\n//\n// This mechanism can be used to report any kind of progress including work done progress (usually used to report progress in the user interface using a progress bar) and\n// partial result progress to support streaming of results.\n//\n// @since 3.16.0.\nfunc (c *client) Progress(ctx context.Context, params *ProgressParams) (err error) {\n\tc.logger.Debug(\"call \" + MethodProgress)\n\tdefer c.logger.Debug(\"end \"+MethodProgress, slog.Any(\"error\", err))\n\n\treturn c.Notify(ctx, MethodProgress, params)\n}\n\n// WorkDoneProgressCreate sends the request is sent from the server to the client to ask the client to create a work done progress.\n//\n// @since 3.16.0.\nfunc (c *client) WorkDoneProgressCreate(ctx context.Context, params *WorkDoneProgressCreateParams) (err error) {\n\tc.logger.Debug(\"call \" + MethodWorkDoneProgressCreate)\n\tdefer c.logger.Debug(\"end \"+MethodWorkDoneProgressCreate, slog.Any(\"error\", err))\n\n\treturn Call(ctx, c.Conn, MethodWorkDoneProgressCreate, params, nil)\n}\n\n// LogMessage sends the notification from the server to the client to ask the client to log a particular message.\nfunc (c *client) LogMessage(ctx context.Context, params *LogMessageParams) (err error) {\n\tc.logger.Debug(\"call \" + MethodWindowLogMessage)\n\tdefer c.logger.Debug(\"end \"+MethodWindowLogMessage, slog.Any(\"error\", err))\n\n\treturn c.Notify(ctx, MethodWindowLogMessage, params)\n}\n\n// PublishDiagnostics sends the notification from the server to the client to signal results of validation runs.\n//\n// Diagnostics are “owned” by the server so it is the server’s responsibility to clear them if necessary. The following rule is used for VS Code servers that generate diagnostics:\n//\n// - if a language is single file only (for example HTML) then diagnostics are cleared by the server when the file is closed.\n// - if a language has a project system (for example C#) diagnostics are not cleared when a file closes. When a project is opened all diagnostics for all files are recomputed (or read from a cache).\n//\n// When a file changes it is the server’s responsibility to re-compute diagnostics and push them to the client.\n// If the computed set is empty it has to push the empty array to clear former diagnostics.\n// Newly pushed diagnostics always replace previously pushed diagnostics. There is no merging that happens on the client side.\nfunc (c *client) PublishDiagnostics(ctx context.Context, params *PublishDiagnosticsParams) (err error) {\n\tc.logger.Debug(\"call \" + MethodTextDocumentPublishDiagnostics)\n\tdefer c.logger.Debug(\"end \"+MethodTextDocumentPublishDiagnostics, slog.Any(\"error\", err))\n\n\treturn c.Notify(ctx, MethodTextDocumentPublishDiagnostics, params)\n}\n\n// ShowMessage sends the notification from a server to a client to ask the\n// client to display a particular message in the user interface.\nfunc (c *client) ShowMessage(ctx context.Context, params *ShowMessageParams) (err error) {\n\treturn c.Notify(ctx, MethodWindowShowMessage, params)\n}\n\n// ShowMessageRequest sends the request from a server to a client to ask the client to display a particular message in the user interface.\n//\n// In addition to the show message notification the request allows to pass actions and to wait for an answer from the client.\nfunc (c *client) ShowMessageRequest(ctx context.Context, params *ShowMessageRequestParams) (_ *MessageActionItem, err error) {\n\tc.logger.Debug(\"call \" + MethodWindowShowMessageRequest)\n\tdefer c.logger.Debug(\"end \"+MethodWindowShowMessageRequest, slog.Any(\"error\", err))\n\n\tvar result *MessageActionItem\n\tif err := Call(ctx, c.Conn, MethodWindowShowMessageRequest, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Telemetry sends the notification from the server to the client to ask the client to log a telemetry event.\nfunc (c *client) Telemetry(ctx context.Context, params any) (err error) {\n\tc.logger.Debug(\"call \" + MethodTelemetryEvent)\n\tdefer c.logger.Debug(\"end \"+MethodTelemetryEvent, slog.Any(\"error\", err))\n\n\treturn c.Notify(ctx, MethodTelemetryEvent, params)\n}\n\n// RegisterCapability sends the request from the server to the client to register for a new capability on the client side.\n//\n// Not all clients need to support dynamic capability registration.\n//\n// A client opts in via the dynamicRegistration property on the specific client capabilities.\n// A client can even provide dynamic registration for capability A but not for capability B (see TextDocumentClientCapabilities as an example).\nfunc (c *client) RegisterCapability(ctx context.Context, params *RegistrationParams) (err error) {\n\tc.logger.Debug(\"call \" + MethodClientRegisterCapability)\n\tdefer c.logger.Debug(\"end \"+MethodClientRegisterCapability, slog.Any(\"error\", err))\n\n\treturn Call(ctx, c.Conn, MethodClientRegisterCapability, params, nil)\n}\n\n// UnregisterCapability sends the request from the server to the client to unregister a previously registered capability.\nfunc (c *client) UnregisterCapability(ctx context.Context, params *UnregistrationParams) (err error) {\n\tc.logger.Debug(\"call \" + MethodClientUnregisterCapability)\n\tdefer c.logger.Debug(\"end \"+MethodClientUnregisterCapability, slog.Any(\"error\", err))\n\n\treturn Call(ctx, c.Conn, MethodClientUnregisterCapability, params, nil)\n}\n\n// ApplyEdit sends the request from the server to the client to modify resource on the client side.\nfunc (c *client) ApplyEdit(ctx context.Context, params *ApplyWorkspaceEditParams) (result *ApplyWorkspaceEditResponse, err error) {\n\tc.logger.Debug(\"call \" + MethodWorkspaceApplyEdit)\n\tdefer c.logger.Debug(\"end \"+MethodWorkspaceApplyEdit, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, c.Conn, MethodWorkspaceApplyEdit, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Configuration sends the request from the server to the client to fetch configuration settings from the client.\n//\n// The request can fetch several configuration settings in one roundtrip.\n// The order of the returned configuration settings correspond to the order of the\n// passed ConfigurationItems (e.g. the first item in the response is the result for the first configuration item in the params).\nfunc (c *client) Configuration(ctx context.Context, params *ConfigurationParams) (_ []any, err error) {\n\tc.logger.Debug(\"call \" + MethodWorkspaceConfiguration)\n\tdefer c.logger.Debug(\"end \"+MethodWorkspaceConfiguration, slog.Any(\"error\", err))\n\n\tvar result []any\n\tif err := Call(ctx, c.Conn, MethodWorkspaceConfiguration, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// WorkspaceFolders sends the request from the server to the client to fetch the current open list of workspace folders.\n//\n// Returns null in the response if only a single file is open in the tool. Returns an empty array if a workspace is open but no folders are configured.\n//\n// @since 3.6.0.\nfunc (c *client) WorkspaceFolders(ctx context.Context) (result []WorkspaceFolder, err error) {\n\tc.logger.Debug(\"call \" + MethodWorkspaceWorkspaceFolders)\n\tdefer c.logger.Debug(\"end \"+MethodWorkspaceWorkspaceFolders, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, c.Conn, MethodWorkspaceWorkspaceFolders, nil, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "lsp/protocol/context.go",
    "content": "// SPDX-FileCopyrightText: 2020 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"context\"\n)\n\ntype ctxClientKey int\n\nvar ctxClient ctxClientKey = 0\n\n// WithClient returns the context with Client value.\nfunc WithClient(ctx context.Context, client Client) context.Context {\n\treturn context.WithValue(ctx, ctxClient, client)\n}\n\n// ClientFromContext extracts Client from context.\nfunc ClientFromContext(ctx context.Context) Client {\n\tclient, ok := ctx.Value(ctxClient).(Client)\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn client\n}\n"
  },
  {
    "path": "lsp/protocol/deprecated.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// ClientCapabilitiesShowDocument alias of ShowDocumentClientCapabilities.\n//\n// Deprecated: Use ShowDocumentClientCapabilities instead.\ntype ClientCapabilitiesShowDocument = ShowDocumentClientCapabilities\n\n// ClientCapabilitiesShowMessageRequest alias of ShowMessageRequestClientCapabilities.\n//\n// Deprecated: Use ShowMessageRequestClientCapabilities instead.\ntype ClientCapabilitiesShowMessageRequest = ShowMessageRequestClientCapabilities\n\n// ClientCapabilitiesShowMessageRequestMessageActionItem alias of ShowMessageRequestClientCapabilitiesMessageActionItem.\n//\n// Deprecated: Use ShowMessageRequestClientCapabilitiesMessageActionItem instead.\ntype ClientCapabilitiesShowMessageRequestMessageActionItem = ShowMessageRequestClientCapabilitiesMessageActionItem\n\n// ReferencesParams alias of ReferenceParams.\n//\n// Deprecated: Use ReferenceParams instead.\ntype ReferencesParams = ReferenceParams\n\n// TextDocumentClientCapabilitiesCallHierarchy alias of CallHierarchyClientCapabilities.\n//\n// Deprecated: Use CallHierarchyClientCapabilities instead.\ntype TextDocumentClientCapabilitiesCallHierarchy = CallHierarchyClientCapabilities\n\n// TextDocumentClientCapabilitiesCodeAction alias of CodeActionClientCapabilities.\n//\n// Deprecated: Use CodeActionClientCapabilities instead.\ntype TextDocumentClientCapabilitiesCodeAction = CodeActionClientCapabilities\n\n// TextDocumentClientCapabilitiesCodeActionKind alias of CodeActionClientCapabilitiesKind.\n//\n// Deprecated: Use CodeActionClientCapabilitiesKind instead.\ntype TextDocumentClientCapabilitiesCodeActionKind = CodeActionClientCapabilitiesKind\n\n// TextDocumentClientCapabilitiesCodeActionLiteralSupport alias of CodeActionClientCapabilitiesLiteralSupport.\n//\n// Deprecated: Use CodeActionClientCapabilitiesLiteralSupport instead.\ntype TextDocumentClientCapabilitiesCodeActionLiteralSupport = CodeActionClientCapabilitiesLiteralSupport\n\n// TextDocumentClientCapabilitiesCodeActionResolveSupport alias of CodeActionClientCapabilitiesResolveSupport.\n//\n// Deprecated: Use CodeActionClientCapabilitiesResolveSupport instead.\ntype TextDocumentClientCapabilitiesCodeActionResolveSupport = CodeActionClientCapabilitiesResolveSupport\n\n// TextDocumentClientCapabilitiesCodeLens alias of CodeLensClientCapabilities.\n//\n// Deprecated: Use CodeLensClientCapabilities instead.\ntype TextDocumentClientCapabilitiesCodeLens = CodeLensClientCapabilities\n\n// TextDocumentClientCapabilitiesColorProvider alias of DocumentColorClientCapabilities.\n//\n// Deprecated: Use DocumentColorClientCapabilities instead.\ntype TextDocumentClientCapabilitiesColorProvider = DocumentColorClientCapabilities\n\n// TextDocumentClientCapabilitiesCompletion alias of CompletionTextDocumentClientCapabilities.\n//\n// Deprecated: Use CompletionTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesCompletion = CompletionTextDocumentClientCapabilities\n\n// TextDocumentClientCapabilitiesCompletionItem alias of CompletionTextDocumentClientCapabilitiesItem.\n//\n// Deprecated: Use CompletionTextDocumentClientCapabilitiesItem instead.\ntype TextDocumentClientCapabilitiesCompletionItem = CompletionTextDocumentClientCapabilitiesItem\n\n// TextDocumentClientCapabilitiesCompletionItemInsertTextModeSupport alias of CompletionTextDocumentClientCapabilitiesItemInsertTextModeSupport.\n//\n// Deprecated: Use CompletionTextDocumentClientCapabilitiesItemInsertTextModeSupport instead.\ntype TextDocumentClientCapabilitiesCompletionItemInsertTextModeSupport = CompletionTextDocumentClientCapabilitiesItemInsertTextModeSupport\n\n// TextDocumentClientCapabilitiesCompletionItemKind alias of CompletionTextDocumentClientCapabilitiesItemKind.\n//\n// Deprecated: Use CompletionTextDocumentClientCapabilitiesItemKind instead.\ntype TextDocumentClientCapabilitiesCompletionItemKind = CompletionTextDocumentClientCapabilitiesItemKind\n\n// TextDocumentClientCapabilitiesCompletionItemResolveSupport alias of CompletionTextDocumentClientCapabilitiesItemResolveSupport.\n//\n// Deprecated: Use CompletionTextDocumentClientCapabilitiesItemResolveSupport instead.\ntype TextDocumentClientCapabilitiesCompletionItemResolveSupport = CompletionTextDocumentClientCapabilitiesItemResolveSupport\n\n// TextDocumentClientCapabilitiesCompletionItemTagSupport alias of CompletionTextDocumentClientCapabilitiesItemTagSupport.\n//\n// Deprecated: Use CompletionTextDocumentClientCapabilitiesItemTagSupport instead.\ntype TextDocumentClientCapabilitiesCompletionItemTagSupport = CompletionTextDocumentClientCapabilitiesItemTagSupport\n\n// TextDocumentClientCapabilitiesDeclaration alias of DeclarationTextDocumentClientCapabilities.\n//\n// Deprecated: Use DeclarationTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesDeclaration = DeclarationTextDocumentClientCapabilities\n\n// TextDocumentClientCapabilitiesDefinition alias of DefinitionTextDocumentClientCapabilities.\n//\n// Deprecated: Use DefinitionTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesDefinition = DefinitionTextDocumentClientCapabilities\n\n// TextDocumentClientCapabilitiesDocumentHighlight alias of DocumentHighlightClientCapabilities.\n//\n// Deprecated: Use DocumentHighlightClientCapabilities instead.\ntype TextDocumentClientCapabilitiesDocumentHighlight = DocumentHighlightClientCapabilities\n\n// TextDocumentClientCapabilitiesDocumentLink alias of DocumentLinkClientCapabilities.\n//\n// Deprecated: Use DocumentLinkClientCapabilities instead.\ntype TextDocumentClientCapabilitiesDocumentLink = DocumentLinkClientCapabilities\n\n// TextDocumentClientCapabilitiesDocumentSymbol alias of DocumentSymbolClientCapabilities.\n//\n// Deprecated: Use DocumentSymbolClientCapabilities instead.\ntype TextDocumentClientCapabilitiesDocumentSymbol = DocumentSymbolClientCapabilities\n\n// TextDocumentClientCapabilitiesDocumentSymbolTagSupport alias of DocumentSymbolClientCapabilitiesTagSupport.\n//\n// Deprecated: Use DocumentSymbolClientCapabilitiesTagSupport instead.\ntype TextDocumentClientCapabilitiesDocumentSymbolTagSupport = DocumentSymbolClientCapabilitiesTagSupport\n\n// TextDocumentClientCapabilitiesFoldingRange alias of FoldingRangeClientCapabilities.\n//\n// Deprecated: Use FoldingRangeClientCapabilities instead.\ntype TextDocumentClientCapabilitiesFoldingRange = FoldingRangeClientCapabilities\n\n// TextDocumentClientCapabilitiesFormatting alias of DocumentFormattingClientCapabilities.\n//\n// Deprecated: Use DocumentFormattingClientCapabilities instead.\ntype TextDocumentClientCapabilitiesFormatting = DocumentFormattingClientCapabilities\n\n// TextDocumentClientCapabilitiesHover alias of HoverTextDocumentClientCapabilities.\n//\n// Deprecated: Use HoverTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesHover = HoverTextDocumentClientCapabilities\n\n// TextDocumentClientCapabilitiesImplementation alias of ImplementationTextDocumentClientCapabilities.\n//\n// Deprecated: Use ImplementationTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesImplementation = ImplementationTextDocumentClientCapabilities\n\n// TextDocumentClientCapabilitiesLinkedEditingRange alias of LinkedEditingRangeClientCapabilities.\n//\n// Deprecated: Use LinkedEditingRangeClientCapabilities instead.\ntype TextDocumentClientCapabilitiesLinkedEditingRange = LinkedEditingRangeClientCapabilities\n\n// TextDocumentClientCapabilitiesMoniker of MonikerClientCapabilities.\n//\n// Deprecated: Use MonikerClientCapabilities instead.\ntype TextDocumentClientCapabilitiesMoniker = MonikerClientCapabilities\n\n// TextDocumentClientCapabilitiesOnTypeFormatting of DocumentOnTypeFormattingClientCapabilities.\n//\n// Deprecated: Use DocumentOnTypeFormattingClientCapabilities instead.\ntype TextDocumentClientCapabilitiesOnTypeFormatting = DocumentOnTypeFormattingClientCapabilities\n\n// TextDocumentClientCapabilitiesPublishDiagnostics of PublishDiagnosticsClientCapabilities.\n//\n// Deprecated: Use PublishDiagnosticsClientCapabilities instead.\ntype TextDocumentClientCapabilitiesPublishDiagnostics = PublishDiagnosticsClientCapabilities\n\n// TextDocumentClientCapabilitiesPublishDiagnosticsTagSupport of PublishDiagnosticsClientCapabilitiesTagSupport.\n//\n// Deprecated: Use PublishDiagnosticsClientCapabilitiesTagSupport instead.\ntype TextDocumentClientCapabilitiesPublishDiagnosticsTagSupport = PublishDiagnosticsClientCapabilitiesTagSupport\n\n// TextDocumentClientCapabilitiesRangeFormatting of DocumentRangeFormattingClientCapabilities.\n//\n// Deprecated: Use DocumentRangeFormattingClientCapabilities instead.\ntype TextDocumentClientCapabilitiesRangeFormatting = DocumentRangeFormattingClientCapabilities\n\n// TextDocumentClientCapabilitiesReferences of ReferencesTextDocumentClientCapabilities.\n//\n// Deprecated: Use ReferencesTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesReferences = ReferencesTextDocumentClientCapabilities\n\n// TextDocumentClientCapabilitiesRename of RenameClientCapabilities.\n//\n// Deprecated: Use RenameClientCapabilities instead.\ntype TextDocumentClientCapabilitiesRename = RenameClientCapabilities\n\n// TextDocumentClientCapabilitiesSelectionRange of SelectionRangeClientCapabilities.\n//\n// Deprecated: Use SelectionRangeClientCapabilities instead.\ntype TextDocumentClientCapabilitiesSelectionRange = SelectionRangeClientCapabilities\n\n// TextDocumentClientCapabilitiesSemanticTokens of SemanticTokensClientCapabilities.\n//\n// Deprecated: Use SemanticTokensClientCapabilities instead.\ntype TextDocumentClientCapabilitiesSemanticTokens = SemanticTokensClientCapabilities\n\n// TextDocumentClientCapabilitiesSignatureHelp of SignatureHelpTextDocumentClientCapabilities.\n//\n// Deprecated: Use SignatureHelpTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesSignatureHelp = SignatureHelpTextDocumentClientCapabilities\n\n// TextDocumentClientCapabilitiesSynchronization of TextDocumentSyncClientCapabilities.\n//\n// Deprecated: Use TextDocumentSyncClientCapabilities instead.\ntype TextDocumentClientCapabilitiesSynchronization = TextDocumentSyncClientCapabilities\n\n// TextDocumentClientCapabilitiesTypeDefinition of TypeDefinitionTextDocumentClientCapabilities.\n//\n// Deprecated: Use TypeDefinitionTextDocumentClientCapabilities instead.\ntype TextDocumentClientCapabilitiesTypeDefinition = TypeDefinitionTextDocumentClientCapabilities\n\n// Abort alias of FailureHandlingKindAbort.\n//\n// Deprecated: Use FailureHandlingKindAbort instead.\nconst Abort = FailureHandlingKindAbort\n\n// TextOnlyTransactional alias of FailureHandlingKindTextOnlyTransactional.\n//\n// Deprecated: Use FailureHandlingKindTextOnlyTransactional instead.\nconst TextOnlyTransactional = FailureHandlingKindTextOnlyTransactional\n\n// Transactional alias of FailureHandlingKindTransactional.\n//\n// Deprecated: Use FailureHandlingKindTransactional instead.\nconst Transactional = FailureHandlingKindTransactional\n\n// Undo alias of FailureHandlingKindUndo.\n//\n// Deprecated: Use FailureHandlingKindUndo instead.\nconst Undo = FailureHandlingKindUndo\n\n// WorkspaceClientCapabilitiesSymbol alias of WorkspaceSymbolClientCapabilities.\n//\n// Deprecated: Use WorkspaceSymbolClientCapabilities instead.\ntype WorkspaceClientCapabilitiesSymbol = WorkspaceSymbolClientCapabilities\n\n// WorkspaceClientCapabilitiesSymbolKind alias of SymbolKindCapabilities.\n//\n// Deprecated: Use SymbolKindCapabilities instead.\ntype WorkspaceClientCapabilitiesSymbolKind = SymbolKindCapabilities\n\n// WorkspaceClientCapabilitiesCodeLens alias of CodeLensWorkspaceClientCapabilities.\n//\n// Deprecated: Use CodeLensWorkspaceClientCapabilities instead.\ntype WorkspaceClientCapabilitiesCodeLens = CodeLensWorkspaceClientCapabilities\n\n// WorkspaceClientCapabilitiesDidChangeConfiguration alias of DidChangeConfigurationWorkspaceClientCapabilities.\n//\n// Deprecated: Use DidChangeConfigurationWorkspaceClientCapabilities instead.\ntype WorkspaceClientCapabilitiesDidChangeConfiguration = DidChangeConfigurationWorkspaceClientCapabilities\n\n// WorkspaceClientCapabilitiesDidChangeWatchedFiles alias of DidChangeWatchedFilesWorkspaceClientCapabilities.\n//\n// Deprecated: Use DidChangeWatchedFilesWorkspaceClientCapabilities instead.\ntype WorkspaceClientCapabilitiesDidChangeWatchedFiles = DidChangeWatchedFilesWorkspaceClientCapabilities\n\n// WorkspaceClientCapabilitiesExecuteCommand alias of ExecuteCommandClientCapabilities.\n//\n// Deprecated: Use ExecuteCommandClientCapabilities instead.\ntype WorkspaceClientCapabilitiesExecuteCommand = ExecuteCommandClientCapabilities\n\n// WorkspaceClientCapabilitiesSemanticTokens alias of SemanticTokensWorkspaceClientCapabilities.\n//\n// Deprecated: Use SemanticTokensWorkspaceClientCapabilities instead.\ntype WorkspaceClientCapabilitiesSemanticTokens = SemanticTokensWorkspaceClientCapabilities\n\n// WorkspaceClientCapabilitiesSemanticTokensRequests alias of SemanticTokensWorkspaceClientCapabilitiesRequests.\n//\n// Deprecated: Use SemanticTokensWorkspaceClientCapabilitiesRequests instead.\ntype WorkspaceClientCapabilitiesSemanticTokensRequests = SemanticTokensWorkspaceClientCapabilitiesRequests\n"
  },
  {
    "path": "lsp/protocol/diagnostics.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"strconv\"\n)\n\n// Diagnostic represents a diagnostic, such as a compiler error or warning.\n//\n// Diagnostic objects are only valid in the scope of a resource.\ntype Diagnostic struct {\n\t// Range is the range at which the message applies.\n\tRange Range `json:\"range\"`\n\n\t// Severity is the diagnostic's severity. Can be omitted. If omitted it is up to the\n\t// client to interpret diagnostics as error, warning, info or hint.\n\tSeverity DiagnosticSeverity `json:\"severity,omitempty\"`\n\n\t// Code is the diagnostic's code, which might appear in the user interface.\n\tCode any `json:\"code,omitempty\"` // int32 | string;\n\n\t// CodeDescription an optional property to describe the error code.\n\t//\n\t// @since 3.16.0.\n\tCodeDescription *CodeDescription `json:\"codeDescription,omitempty\"`\n\n\t// Source a human-readable string describing the source of this\n\t// diagnostic, e.g. 'typescript' or 'super lint'.\n\tSource string `json:\"source,omitempty\"`\n\n\t// Message is the diagnostic's message.\n\tMessage string `json:\"message\"`\n\n\t// Tags is the additional metadata about the diagnostic.\n\t//\n\t// @since 3.15.0.\n\tTags []DiagnosticTag `json:\"tags,omitempty\"`\n\n\t// RelatedInformation an array of related diagnostic information, e.g. when symbol-names within\n\t// a scope collide all definitions can be marked via this property.\n\tRelatedInformation []DiagnosticRelatedInformation `json:\"relatedInformation,omitempty\"`\n\n\t// Data is a data entry field that is preserved between a\n\t// \"textDocument/publishDiagnostics\" notification and\n\t// \"textDocument/codeAction\" request.\n\t//\n\t// @since 3.16.0.\n\tData any `json:\"data,omitempty\"`\n}\n\n// DiagnosticSeverity indicates the severity of a Diagnostic message.\ntype DiagnosticSeverity float64\n\nconst (\n\t// DiagnosticSeverityError reports an error.\n\tDiagnosticSeverityError DiagnosticSeverity = 1\n\n\t// DiagnosticSeverityWarning reports a warning.\n\tDiagnosticSeverityWarning DiagnosticSeverity = 2\n\n\t// DiagnosticSeverityInformation reports an information.\n\tDiagnosticSeverityInformation DiagnosticSeverity = 3\n\n\t// DiagnosticSeverityHint reports a hint.\n\tDiagnosticSeverityHint DiagnosticSeverity = 4\n)\n\n// String implements fmt.Stringer.\nfunc (d DiagnosticSeverity) String() string {\n\tswitch d {\n\tcase DiagnosticSeverityError:\n\t\treturn \"Error\"\n\tcase DiagnosticSeverityWarning:\n\t\treturn \"Warning\"\n\tcase DiagnosticSeverityInformation:\n\t\treturn \"Information\"\n\tcase DiagnosticSeverityHint:\n\t\treturn \"Hint\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(d), 'f', -10, 64)\n\t}\n}\n\n// CodeDescription is the structure to capture a description for an error code.\n//\n// @since 3.16.0.\ntype CodeDescription struct {\n\t// Href an URI to open with more information about the diagnostic error.\n\tHref URI `json:\"href\"`\n}\n\n// DiagnosticTag is the diagnostic tags.\n//\n// @since 3.15.0.\ntype DiagnosticTag float64\n\n// list of DiagnosticTag.\nconst (\n\t// DiagnosticTagUnnecessary unused or unnecessary code.\n\t//\n\t// Clients are allowed to render diagnostics with this tag faded out instead of having\n\t// an error squiggle.\n\tDiagnosticTagUnnecessary DiagnosticTag = 1\n\n\t// DiagnosticTagDeprecated deprecated or obsolete code.\n\t//\n\t// Clients are allowed to rendered diagnostics with this tag strike through.\n\tDiagnosticTagDeprecated DiagnosticTag = 2\n)\n\n// String implements fmt.Stringer.\nfunc (d DiagnosticTag) String() string {\n\tswitch d {\n\tcase DiagnosticTagUnnecessary:\n\t\treturn \"Unnecessary\"\n\tcase DiagnosticTagDeprecated:\n\t\treturn \"Deprecated\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(d), 'f', -10, 64)\n\t}\n}\n\n// DiagnosticRelatedInformation represents a related message and source code location for a diagnostic.\n//\n// This should be used to point to code locations that cause or related to a diagnostics, e.g when duplicating\n// a symbol in a scope.\ntype DiagnosticRelatedInformation struct {\n\t// Location is the location of this related diagnostic information.\n\tLocation Location `json:\"location\"`\n\n\t// Message is the message of this related diagnostic information.\n\tMessage string `json:\"message\"`\n}\n\n// PublishDiagnosticsParams represents a params of PublishDiagnostics notification.\ntype PublishDiagnosticsParams struct {\n\t// URI is the URI for which diagnostic information is reported.\n\tURI DocumentURI `json:\"uri\"`\n\n\t// Version optional the version number of the document the diagnostics are published for.\n\t//\n\t// @since 3.15\n\tVersion uint32 `json:\"version,omitempty\"`\n\n\t// Diagnostics an array of diagnostic information items.\n\tDiagnostics []Diagnostic `json:\"diagnostics\"`\n}\n"
  },
  {
    "path": "lsp/protocol/diagnostics_test.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\nfunc TestDiagnostic(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant                      = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"severity\":1,\"code\":\"foo/bar\",\"codeDescription\":{\"href\":\"file:///path/to/test.go\"},\"source\":\"test foo bar\",\"message\":\"foo bar\",\"tags\":[1,2],\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"basic_gen.go\"}],\"data\":\"testData\"}`\n\t\twantNilSeverity           = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"code\":\"foo/bar\",\"codeDescription\":{\"href\":\"file:///path/to/test.go\"},\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"basic_gen.go\"}],\"data\":\"testData\"}`\n\t\twantNilCode               = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"severity\":1,\"codeDescription\":{\"href\":\"file:///path/to/test.go\"},\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"basic_gen.go\"}],\"data\":\"testData\"}`\n\t\twantNilRelatedInformation = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"severity\":1,\"code\":\"foo/bar\",\"codeDescription\":{\"href\":\"file:///path/to/test.go\"},\"source\":\"test foo bar\",\"message\":\"foo bar\",\"data\":\"testData\"}`\n\t\twantNilAll                = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"message\":\"foo bar\"}`\n\t\twantInvalid               = `{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"severity\":1,\"code\":\"foo/bar\",\"codeDescription\":{\"href\":\"file:///path/to/test.go\"},\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}},\"message\":\"basic_gen.go\"}],\"data\":\"invalidData\"}`\n\t)\n\twantType := Diagnostic{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tSeverity: DiagnosticSeverityError,\n\t\tCode:     \"foo/bar\",\n\t\tCodeDescription: &CodeDescription{\n\t\t\tHref: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tSource:  \"test foo bar\",\n\t\tMessage: \"foo bar\",\n\t\tTags: []DiagnosticTag{\n\t\t\tDiagnosticTagUnnecessary,\n\t\t\tDiagnosticTagDeprecated,\n\t\t},\n\t\tRelatedInformation: []DiagnosticRelatedInformation{\n\t\t\t{\n\t\t\t\tLocation: Location{\n\t\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tMessage: \"basic_gen.go\",\n\t\t\t},\n\t\t},\n\t\tData: \"testData\",\n\t}\n\twantTypeNilSeverity := Diagnostic{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tCode: \"foo/bar\",\n\t\tCodeDescription: &CodeDescription{\n\t\t\tHref: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tSource:  \"test foo bar\",\n\t\tMessage: \"foo bar\",\n\t\tRelatedInformation: []DiagnosticRelatedInformation{\n\t\t\t{\n\t\t\t\tLocation: Location{\n\t\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tMessage: \"basic_gen.go\",\n\t\t\t},\n\t\t},\n\t\tData: \"testData\",\n\t}\n\twantTypeNilCode := Diagnostic{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tSeverity: DiagnosticSeverityError,\n\t\tCodeDescription: &CodeDescription{\n\t\t\tHref: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tSource:  \"test foo bar\",\n\t\tMessage: \"foo bar\",\n\t\tRelatedInformation: []DiagnosticRelatedInformation{\n\t\t\t{\n\t\t\t\tLocation: Location{\n\t\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tMessage: \"basic_gen.go\",\n\t\t\t},\n\t\t},\n\t\tData: \"testData\",\n\t}\n\twantTypeNilRelatedInformation := Diagnostic{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tSeverity: DiagnosticSeverityError,\n\t\tCode:     \"foo/bar\",\n\t\tCodeDescription: &CodeDescription{\n\t\t\tHref: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tSource:  \"test foo bar\",\n\t\tMessage: \"foo bar\",\n\t\tData:    \"testData\",\n\t}\n\twantTypeNilAll := Diagnostic{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tMessage: \"foo bar\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Diagnostic\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilSeverity\",\n\t\t\t\tfield:          wantTypeNilSeverity,\n\t\t\t\twant:           wantNilSeverity,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilCode\",\n\t\t\t\tfield:          wantTypeNilCode,\n\t\t\t\twant:           wantNilCode,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilRelatedInformation\",\n\t\t\t\tfield:          wantTypeNilRelatedInformation,\n\t\t\t\twant:           wantNilRelatedInformation,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Diagnostic\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilSeverity\",\n\t\t\t\tfield:            wantNilSeverity,\n\t\t\t\twant:             wantTypeNilSeverity,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilCode\",\n\t\t\t\tfield:            wantNilCode,\n\t\t\t\twant:             wantTypeNilCode,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilRelatedInformation\",\n\t\t\t\tfield:            wantNilRelatedInformation,\n\t\t\t\twant:             wantTypeNilRelatedInformation,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Diagnostic\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDiagnosticSeverity_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\td    DiagnosticSeverity\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Error\",\n\t\t\td:    DiagnosticSeverityError,\n\t\t\twant: \"Error\",\n\t\t},\n\t\t{\n\t\t\tname: \"Warning\",\n\t\t\td:    DiagnosticSeverityWarning,\n\t\t\twant: \"Warning\",\n\t\t},\n\t\t{\n\t\t\tname: \"Information\",\n\t\t\td:    DiagnosticSeverityInformation,\n\t\t\twant: \"Information\",\n\t\t},\n\t\t{\n\t\t\tname: \"Hint\",\n\t\t\td:    DiagnosticSeverityHint,\n\t\t\twant: \"Hint\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\td:    DiagnosticSeverity(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.d.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"DiagnosticSeverity.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDiagnosticTag_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\td    DiagnosticTag\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Unnecessary\",\n\t\t\td:    DiagnosticTagUnnecessary,\n\t\t\twant: \"Unnecessary\",\n\t\t},\n\t\t{\n\t\t\tname: \"Deprecated\",\n\t\t\td:    DiagnosticTagDeprecated,\n\t\t\twant: \"Deprecated\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\td:    DiagnosticTag(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.d.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"DiagnosticSeverity.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDiagnosticRelatedInformation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"location\":{\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"basic_gen.go\"}`\n\t\twantInvalid = `{\"location\":{\"uri\":\"file:///path/to/basic.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}},\"message\":\"basic_gen.go\"}`\n\t)\n\twantType := DiagnosticRelatedInformation{\n\t\tLocation: Location{\n\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tMessage: \"basic_gen.go\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DiagnosticRelatedInformation\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DiagnosticRelatedInformation\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DiagnosticRelatedInformation\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestPublishDiagnosticsParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"uri\":\"file:///path/to/diagnostics.go\",\"version\":1,\"diagnostics\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/diagnostics.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"diagnostics.go\"}]}]}`\n\t\twantInvalid = `{\"uri\":\"file:///path/to/diagnostics_gen.go\",\"version\":2,\"diagnostics\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/diagnostics_gen.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}},\"message\":\"diagnostics_gen.go\"}]}]}`\n\t)\n\twantType := PublishDiagnosticsParams{\n\t\tURI:     DocumentURI(\"file:///path/to/diagnostics.go\"),\n\t\tVersion: 1,\n\t\tDiagnostics: []Diagnostic{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSeverity: DiagnosticSeverityError,\n\t\t\t\tCode:     \"foo/bar\",\n\t\t\t\tSource:   \"test foo bar\",\n\t\t\t\tMessage:  \"foo bar\",\n\t\t\t\tRelatedInformation: []DiagnosticRelatedInformation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLocation: Location{\n\t\t\t\t\t\t\tURI: uri.File(\"/path/to/diagnostics.go\"),\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tMessage: \"diagnostics.go\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          PublishDiagnosticsParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             PublishDiagnosticsParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got PublishDiagnosticsParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/doc.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\n// Package protocol implements Language Server Protocol specification in Go.\n//\n// This package contains the structs that map directly to the wire format\n// of the Language Server Protocol.\n//\n// It is a literal transcription, with unmodified comments, and only the changes\n// required to make it Go code.\n//\n// - Names are uppercased to export them.\n//\n// - All fields have JSON tags added to correct the names.\n//\n// - Fields marked with a ? are also marked as \"omitempty\".\n//\n// - Fields that are \"|| null\" are made pointers.\n//\n// - Fields that are string or number are left as string.\n//\n// - Fields that are type \"number\" are made float64.\npackage protocol // import \"github.com/a-h/templ/lsp/protocol\"\n"
  },
  {
    "path": "lsp/protocol/errors.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport \"github.com/a-h/templ/lsp/jsonrpc2\"\n\nconst (\n\t// LSPReservedErrorRangeStart is the start range of LSP reserved error codes.\n\t//\n\t// It doesn't denote a real error code.\n\t//\n\t// @since 3.16.0.\n\tLSPReservedErrorRangeStart jsonrpc2.Code = -32899\n\n\t// ContentModified is the state change that invalidates the result of a request in execution.\n\t//\n\t// Defined by the protocol.\n\tCodeContentModified jsonrpc2.Code = -32801\n\n\t// RequestCancelled is the cancellation error.\n\t//\n\t// Defined by the protocol.\n\tCodeRequestCancelled jsonrpc2.Code = -32800\n\n\t// LSPReservedErrorRangeEnd is the end range of LSP reserved error codes.\n\t//\n\t// It doesn't denote a real error code.\n\t//\n\t// @since 3.16.0.\n\tLSPReservedErrorRangeEnd jsonrpc2.Code = -32800\n)\n\nvar (\n\t// ErrContentModified should be used when a request is canceled early.\n\tErrContentModified = jsonrpc2.NewError(CodeContentModified, \"cancelled JSON-RPC\")\n\n\t// ErrRequestCancelled should be used when a request is canceled early.\n\tErrRequestCancelled = jsonrpc2.NewError(CodeRequestCancelled, \"cancelled JSON-RPC\")\n)\n"
  },
  {
    "path": "lsp/protocol/general.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// TraceValue represents a InitializeParams Trace mode.\ntype TraceValue string\n\n// list of TraceValue.\nconst (\n\t// TraceOff disable tracing.\n\tTraceOff TraceValue = \"off\"\n\n\t// TraceMessage normal tracing mode.\n\tTraceMessage TraceValue = \"message\"\n\n\t// TraceVerbose verbose tracing mode.\n\tTraceVerbose TraceValue = \"verbose\"\n)\n\n// ClientInfo information about the client.\n//\n// @since 3.15.0.\ntype ClientInfo struct {\n\t// Name is the name of the client as defined by the client.\n\tName string `json:\"name\"`\n\n\t// Version is the client's version as defined by the client.\n\tVersion string `json:\"version,omitempty\"`\n}\n\n// InitializeParams params of Initialize request.\ntype InitializeParams struct {\n\tWorkDoneProgressParams\n\n\t// ProcessID is the process Id of the parent process that started\n\t// the server. Is null if the process has not been started by another process.\n\t// If the parent process is not alive then the server should exit (see exit notification) its process.\n\tProcessID int32 `json:\"processId\"`\n\n\t// ClientInfo is the information about the client.\n\t//\n\t// @since 3.15.0\n\tClientInfo *ClientInfo `json:\"clientInfo,omitempty\"`\n\n\t// Locale is the locale the client is currently showing the user interface\n\t// in. This must not necessarily be the locale of the operating\n\t// system.\n\t//\n\t// Uses IETF language tags as the value's syntax\n\t// (See https://en.wikipedia.org/wiki/IETF_language_tag)\n\t//\n\t// @since 3.16.0.\n\tLocale string `json:\"locale,omitempty\"`\n\n\t// RootPath is the rootPath of the workspace. Is null\n\t// if no folder is open.\n\t//\n\t// Deprecated: Use RootURI instead.\n\tRootPath string `json:\"rootPath,omitempty\"`\n\n\t// RootURI is the rootUri of the workspace. Is null if no\n\t// folder is open. If both `rootPath` and \"rootUri\" are set\n\t// \"rootUri\" wins.\n\t//\n\t// Deprecated: Use WorkspaceFolders instead.\n\tRootURI DocumentURI `json:\"rootUri,omitempty\"`\n\n\t// InitializationOptions user provided initialization options.\n\tInitializationOptions any `json:\"initializationOptions,omitempty\"`\n\n\t// Capabilities is the capabilities provided by the client (editor or tool)\n\tCapabilities ClientCapabilities `json:\"capabilities\"`\n\n\t// Trace is the initial trace setting. If omitted trace is disabled ('off').\n\tTrace TraceValue `json:\"trace,omitempty\"`\n\n\t// WorkspaceFolders is the workspace folders configured in the client when the server starts.\n\t// This property is only available if the client supports workspace folders.\n\t// It can be `null` if the client supports workspace folders but none are\n\t// configured.\n\t//\n\t// @since 3.6.0.\n\tWorkspaceFolders []WorkspaceFolder `json:\"workspaceFolders,omitempty\"`\n}\n\n// InitializeResult result of ClientCapabilities.\ntype InitializeResult struct {\n\t// Capabilities is the capabilities the language server provides.\n\tCapabilities ServerCapabilities `json:\"capabilities\"`\n\n\t// ServerInfo Information about the server.\n\t//\n\t// @since 3.15.0.\n\tServerInfo *ServerInfo `json:\"serverInfo,omitempty\"`\n}\n\n// LogTraceParams params of LogTrace notification.\n//\n// @since 3.16.0.\ntype LogTraceParams struct {\n\t// Message is the message to be logged.\n\tMessage string `json:\"message\"`\n\n\t// Verbose is the additional information that can be computed if the \"trace\" configuration\n\t// is set to \"verbose\".\n\tVerbose TraceValue `json:\"verbose,omitempty\"`\n}\n\n// SetTraceParams params of SetTrace notification.\n//\n// @since 3.16.0.\ntype SetTraceParams struct {\n\t// Value is the new value that should be assigned to the trace setting.\n\tValue TraceValue `json:\"value\"`\n}\n\n// FileOperationPatternKind is a pattern kind describing if a glob pattern matches a file a folder or\n// both.\n//\n// @since 3.16.0.\ntype FileOperationPatternKind string\n\n// list of FileOperationPatternKind.\nconst (\n\t// FileOperationPatternKindFile is the pattern matches a file only.\n\tFileOperationPatternKindFile FileOperationPatternKind = \"file\"\n\n\t// FileOperationPatternKindFolder is the pattern matches a folder only.\n\tFileOperationPatternKindFolder FileOperationPatternKind = \"folder\"\n)\n\n// FileOperationPatternOptions matching options for the file operation pattern.\n//\n// @since 3.16.0.\ntype FileOperationPatternOptions struct {\n\t// IgnoreCase is The pattern should be matched ignoring casing.\n\tIgnoreCase bool `json:\"ignoreCase,omitempty\"`\n}\n\n// FileOperationPattern a pattern to describe in which file operation requests or notifications\n// the server is interested in.\n//\n// @since 3.16.0.\ntype FileOperationPattern struct {\n\t// The glob pattern to match. Glob patterns can have the following syntax:\n\t//  - `*` to match one or more characters in a path segment\n\t//  - `?` to match on one character in a path segment\n\t//  - `**` to match any number of path segments, including none\n\t//  - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript\n\t//    and JavaScript files)\n\t//  - `[]` to declare a range of characters to match in a path segment\n\t//    (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n\t//  - `[!...]` to negate a range of characters to match in a path segment\n\t//    (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but\n\t//    not `example.0`)\n\tGlob string `json:\"glob\"`\n\n\t// Matches whether to match files or folders with this pattern.\n\t//\n\t// Matches both if undefined.\n\tMatches FileOperationPatternKind `json:\"matches,omitempty\"`\n\n\t// Options additional options used during matching.\n\tOptions FileOperationPatternOptions `json:\"options,omitempty\"`\n}\n\n// FileOperationFilter is a filter to describe in which file operation requests or notifications\n// the server is interested in.\n//\n// @since 3.16.0.\ntype FileOperationFilter struct {\n\t// Scheme is a URI like \"file\" or \"untitled\".\n\tScheme string `json:\"scheme,omitempty\"`\n\n\t// Pattern is the actual file operation pattern.\n\tPattern FileOperationPattern `json:\"pattern\"`\n}\n\n// CreateFilesParams is the parameters sent in notifications/requests for user-initiated creation\n// of files.\n//\n// @since 3.16.0.\ntype CreateFilesParams struct {\n\t// Files an array of all files/folders created in this operation.\n\tFiles []FileCreate `json:\"files\"`\n}\n\n// FileCreate nepresents information on a file/folder create.\n//\n// @since 3.16.0.\ntype FileCreate struct {\n\t// URI is a file:// URI for the location of the file/folder being created.\n\tURI string `json:\"uri\"`\n}\n\n// RenameFilesParams is the parameters sent in notifications/requests for user-initiated renames\n// of files.\n//\n// @since 3.16.0.\ntype RenameFilesParams struct {\n\t// Files an array of all files/folders renamed in this operation. When a folder\n\t// is renamed, only the folder will be included, and not its children.\n\tFiles []FileRename `json:\"files\"`\n}\n\n// FileRename represents information on a file/folder rename.\n//\n// @since 3.16.0.\ntype FileRename struct {\n\t// OldURI is a file:// URI for the original location of the file/folder being renamed.\n\tOldURI string `json:\"oldUri\"`\n\n\t// NewURI is a file:// URI for the new location of the file/folder being renamed.\n\tNewURI string `json:\"newUri\"`\n}\n\n// DeleteFilesParams is the parameters sent in notifications/requests for user-initiated deletes\n// of files.\n//\n// @since 3.16.0.\ntype DeleteFilesParams struct {\n\t// Files an array of all files/folders deleted in this operation.\n\tFiles []FileDelete `json:\"files\"`\n}\n\n// FileDelete represents information on a file/folder delete.\n//\n// @since 3.16.0.\ntype FileDelete struct {\n\t// URI is a file:// URI for the location of the file/folder being deleted.\n\tURI string `json:\"uri\"`\n}\n\n// DocumentHighlightParams params of DocumentHighlight request.\n//\n// @since 3.15.0.\ntype DocumentHighlightParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n}\n\n// DeclarationParams params of Declaration request.\n//\n// @since 3.15.0.\ntype DeclarationParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n}\n\n// DefinitionParams params of Definition request.\n//\n// @since 3.15.0.\ntype DefinitionParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n}\n\n// TypeDefinitionParams params of TypeDefinition request.\n//\n// @since 3.15.0.\ntype TypeDefinitionParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n}\n\n// ImplementationParams params of Implementation request.\n//\n// @since 3.15.0.\ntype ImplementationParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n}\n\n// ShowDocumentParams params to show a document.\n//\n// @since 3.16.0.\ntype ShowDocumentParams struct {\n\t// URI is the document uri to show.\n\tURI URI `json:\"uri\"`\n\n\t// External indicates to show the resource in an external program.\n\t// To show for example `https://code.visualstudio.com/`\n\t// in the default WEB browser set `external` to `true`.\n\tExternal bool `json:\"external,omitempty\"`\n\n\t// TakeFocus an optional property to indicate whether the editor\n\t// showing the document should take focus or not.\n\t// Clients might ignore this property if an external\n\t// program is started.\n\tTakeFocus bool `json:\"takeFocus,omitempty\"`\n\n\t// Selection an optional selection range if the document is a text\n\t// document. Clients might ignore the property if an\n\t// external program is started or the file is not a text\n\t// file.\n\tSelection *Range `json:\"selection,omitempty\"`\n}\n\n// ShowDocumentResult is the result of an show document request.\n//\n// @since 3.16.0.\ntype ShowDocumentResult struct {\n\t// Success a boolean indicating if the show was successful.\n\tSuccess bool `json:\"success\"`\n}\n\n// ServerInfo Information about the server.\n//\n// @since 3.15.0.\ntype ServerInfo struct {\n\t// Name is the name of the server as defined by the server.\n\tName string `json:\"name\"`\n\n\t// Version is the server's version as defined by the server.\n\tVersion string `json:\"version,omitempty\"`\n}\n\n// InitializeError known error codes for an \"InitializeError\".\ntype InitializeError struct {\n\t// Retry indicates whether the client execute the following retry logic:\n\t// (1) show the message provided by the ResponseError to the user\n\t// (2) user selects retry or cancel\n\t// (3) if user selected retry the initialize method is sent again.\n\tRetry bool `json:\"retry,omitempty\"`\n}\n\n// ReferencesOptions ReferencesProvider options.\n//\n// @since 3.15.0.\ntype ReferencesOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// WorkDoneProgressOptions WorkDoneProgress options.\n//\n// @since 3.15.0.\ntype WorkDoneProgressOptions struct {\n\tWorkDoneProgress bool `json:\"workDoneProgress,omitempty\"`\n}\n\n// LinkedEditingRangeParams params for the LinkedEditingRange request.\n//\n// @since 3.16.0.\ntype LinkedEditingRangeParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n}\n\n// LinkedEditingRanges result of LinkedEditingRange request.\n//\n// @since 3.16.0.\ntype LinkedEditingRanges struct {\n\t// Ranges a list of ranges that can be renamed together.\n\t//\n\t// The ranges must have identical length and contain identical text content.\n\t//\n\t// The ranges cannot overlap.\n\tRanges []Range `json:\"ranges\"`\n\n\t// WordPattern an optional word pattern (regular expression) that describes valid contents for\n\t// the given ranges.\n\t//\n\t// If no pattern is provided, the client configuration's word pattern will be used.\n\tWordPattern string `json:\"wordPattern,omitempty\"`\n}\n\n// MonikerParams params for the Moniker request.\n//\n// @since 3.16.0.\ntype MonikerParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n}\n\n// UniquenessLevel is the Moniker uniqueness level to define scope of the moniker.\n//\n// @since 3.16.0.\ntype UniquenessLevel string\n\n// list of UniquenessLevel.\nconst (\n\t// UniquenessLevelDocument is the moniker is only unique inside a document.\n\tUniquenessLevelDocument UniquenessLevel = \"document\"\n\n\t// UniquenessLevelProject is the moniker is unique inside a project for which a dump got created.\n\tUniquenessLevelProject UniquenessLevel = \"project\"\n\n\t// UniquenessLevelGroup is the moniker is unique inside the group to which a project belongs.\n\tUniquenessLevelGroup UniquenessLevel = \"group\"\n\n\t// UniquenessLevelScheme is the moniker is unique inside the moniker scheme.\n\tUniquenessLevelScheme UniquenessLevel = \"scheme\"\n\n\t// UniquenessLevelGlobal is the moniker is globally unique.\n\tUniquenessLevelGlobal UniquenessLevel = \"global\"\n)\n\n// MonikerKind is the moniker kind.\n//\n// @since 3.16.0.\ntype MonikerKind string\n\n// list of MonikerKind.\nconst (\n\t// MonikerKindImport is the moniker represent a symbol that is imported into a project.\n\tMonikerKindImport MonikerKind = \"import\"\n\n\t// MonikerKindExport is the moniker represents a symbol that is exported from a project.\n\tMonikerKindExport MonikerKind = \"export\"\n\n\t// MonikerKindLocal is the moniker represents a symbol that is local to a project (e.g. a local\n\t// variable of a function, a class not visible outside the project, ...).\n\tMonikerKindLocal MonikerKind = \"local\"\n)\n\n// Moniker definition to match LSIF 0.5 moniker definition.\n//\n// @since 3.16.0.\ntype Moniker struct {\n\t// Scheme is the scheme of the moniker. For example tsc or .Net.\n\tScheme string `json:\"scheme\"`\n\n\t// Identifier is the identifier of the moniker.\n\t//\n\t// The value is opaque in LSIF however schema owners are allowed to define the structure if they want.\n\tIdentifier string `json:\"identifier\"`\n\n\t// Unique is the scope in which the moniker is unique.\n\tUnique UniquenessLevel `json:\"unique\"`\n\n\t// Kind is the moniker kind if known.\n\tKind MonikerKind `json:\"kind,omitempty\"`\n}\n\n// StaticRegistrationOptions staticRegistration options to be returned in the initialize request.\ntype StaticRegistrationOptions struct {\n\t// ID is the id used to register the request. The id can be used to deregister\n\t// the request again. See also Registration#id.\n\tID string `json:\"id,omitempty\"`\n}\n\n// DocumentLinkRegistrationOptions DocumentLinkRegistration options.\ntype DocumentLinkRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// ResolveProvider document links have a resolve provider as well.\n\tResolveProvider bool `json:\"resolveProvider,omitempty\"`\n}\n\n// InitializedParams params of Initialized notification.\ntype InitializedParams struct{}\n\n// WorkspaceFolders represents a slice of WorkspaceFolder.\ntype WorkspaceFolders []WorkspaceFolder\n"
  },
  {
    "path": "lsp/protocol/general_test.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\nfunc TestWorkspaceFolders(t *testing.T) {\n\tt.Parallel()\n\n\tconst want = `[{\"uri\":\"file:///Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\",\"name\":\"protocol\"},{\"uri\":\"file:///Users/zchee/go/src/github.com/a-h/templ/lsp/jsonrpc2\",\"name\":\"jsonrpc2\"}]`\n\twantType := WorkspaceFolders{\n\t\t{\n\t\t\tURI:  string(uri.File(\"/Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\")),\n\t\t\tName: \"protocol\",\n\t\t},\n\t\t{\n\t\t\tURI:  string(uri.File(\"/Users/zchee/go/src/github.com/a-h/templ/lsp/jsonrpc2\")),\n\t\t\tName: \"jsonrpc2\",\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceFolders\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceFolders\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceFolders\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestClientInfo(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant       = `{\"name\":\"testClient\",\"version\":\"v0.0.0\"}`\n\t\twantNilAll = `{\"name\":\"testClient\"}`\n\t)\n\twantType := ClientInfo{\n\t\tName:    \"testClient\",\n\t\tVersion: \"v0.0.0\",\n\t}\n\twantTypeNilAll := ClientInfo{\n\t\tName: \"testClient\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ClientInfo\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ClientInfo\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ClientInfo\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestInitializeParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst wantWorkDoneToken = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\tconst (\n\t\twant    = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"processId\":25556,\"clientInfo\":{\"name\":\"testClient\",\"version\":\"v0.0.0\"},\"locale\":\"en-US\",\"rootPath\":\"~/go/src/github.com/a-h/templ/lsp/protocol\",\"rootUri\":\"file:///Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\",\"initializationOptions\":\"testdata\",\"capabilities\":{},\"trace\":\"on\",\"workspaceFolders\":[{\"uri\":\"file:///Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\",\"name\":\"protocol\"},{\"uri\":\"file:///Users/zchee/go/src/github.com/a-h/templ/lsp/jsonrpc2\",\"name\":\"jsonrpc2\"}]}`\n\t\twantNil = `{\"processId\":25556,\"rootUri\":\"file:///Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\",\"capabilities\":{}}`\n\t)\n\twantType := InitializeParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tProcessID: 25556,\n\t\tClientInfo: &ClientInfo{\n\t\t\tName:    \"testClient\",\n\t\t\tVersion: \"v0.0.0\",\n\t\t},\n\t\tLocale:                \"en-US\",\n\t\tRootPath:              \"~/go/src/github.com/a-h/templ/lsp/protocol\",\n\t\tRootURI:               uri.File(\"/Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\"),\n\t\tInitializationOptions: \"testdata\",\n\t\tCapabilities:          ClientCapabilities{},\n\t\tTrace:                 \"on\",\n\t\tWorkspaceFolders: []WorkspaceFolder{\n\t\t\t{\n\t\t\t\tName: filepath.Base(\"/Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\"),\n\t\t\t\tURI:  string(uri.File(\"/Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\")),\n\t\t\t},\n\t\t\t{\n\t\t\t\tName: filepath.Base(\"/Users/zchee/go/src/github.com/a-h/templ/lsp/jsonrpc2\"),\n\t\t\t\tURI:  string(uri.File(\"/Users/zchee/go/src/github.com/a-h/templ/lsp/jsonrpc2\")),\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := InitializeParams{\n\t\tProcessID:    25556,\n\t\tRootURI:      uri.File(\"//Users/zchee/go/src/github.com/a-h/templ/lsp/protocol\"),\n\t\tCapabilities: ClientCapabilities{},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          InitializeParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             InitializeParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got InitializeParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif token := got.WorkDoneToken; token != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(token), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestLogTraceParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"message\":\"testMessage\",\"verbose\":\"verbose\"}`\n\t\twantNil = `{\"message\":\"testMessage\"}`\n\t)\n\twantType := LogTraceParams{\n\t\tMessage: \"testMessage\",\n\t\tVerbose: TraceVerbose,\n\t}\n\twantTypeNil := LogTraceParams{\n\t\tMessage: \"testMessage\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          LogTraceParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             LogTraceParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got LogTraceParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSetTraceParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"value\":\"verbose\"}`\n\t\twantInvalid = `{\"value\":\"invalid\"}`\n\t)\n\twantType := SetTraceParams{\n\t\tValue: TraceVerbose,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SetTraceParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SetTraceParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SetTraceParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCreateFilesParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"files\":[{\"uri\":\"file:///path/to/basic.go\"}]}`\n\t\twantInvalid = `{\"files\":[{\"uri\":\"file:///path/to/invalid.go\"}]}`\n\t)\n\twantType := CreateFilesParams{\n\t\tFiles: []FileCreate{\n\t\t\t{\n\t\t\t\tURI: \"file:///path/to/basic.go\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CreateFilesParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CreateFilesParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CreateFilesParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRenameFilesParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"files\":[{\"oldUri\":\"file:///path/to/old.go\",\"newUri\":\"file:///path/to/new.go\"}]}`\n\t\twantInvalid = `{\"files\":[{\"oldUri\":\"file:///path/to/invalidOld.go\",\"newUri\":\"file:///path/to/invalidNew.go\"}]}`\n\t)\n\twantType := RenameFilesParams{\n\t\tFiles: []FileRename{\n\t\t\t{\n\t\t\t\tOldURI: \"file:///path/to/old.go\",\n\t\t\t\tNewURI: \"file:///path/to/new.go\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RenameFilesParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RenameFilesParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RenameFilesParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDeleteFilesParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"files\":[{\"uri\":\"file:///path/to/basic.go\"}]}`\n\t\twantInvalid = `{\"files\":[{\"uri\":\"file:///path/to/invalid.go\"}]}`\n\t)\n\twantType := DeleteFilesParams{\n\t\tFiles: []FileDelete{\n\t\t\t{\n\t\t\t\tURI: \"file:///path/to/basic.go\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DeleteFilesParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DeleteFilesParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DeleteFilesParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestReferencesParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"context\":{\"includeDeclaration\":true}}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"context\":{\"includeDeclaration\":true}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"context\":{\"includeDeclaration\":false}}`\n\t)\n\twantType := ReferenceParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tContext: ReferenceContext{\n\t\t\tIncludeDeclaration: true,\n\t\t},\n\t}\n\twantTypeNilAll := ReferenceParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tContext: ReferenceContext{\n\t\t\tIncludeDeclaration: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ReferenceParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ReferenceParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ReferenceParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentHighlightOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := DocumentHighlightOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentHighlightOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentHighlightOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentHighlightOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentHighlightOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentHighlightOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentHighlightParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\"}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\"}`\n\t)\n\twantType := DocumentHighlightParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t}\n\twantTypeNilAll := DocumentHighlightParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentHighlightParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentHighlightParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentHighlightParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentSymbolOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true,\"label\":\"testLabel\"}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t\twantNil     = `{}`\n\t)\n\twantType := DocumentSymbolOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t\tLabel: \"testLabel\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentSymbolOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentSymbolOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentSymbolOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentSymbolOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentSymbolOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkspaceSymbolOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t\twantNil     = `{}`\n\t)\n\twantType := WorkspaceSymbolOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceSymbolOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          WorkspaceSymbolOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceSymbolOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             WorkspaceSymbolOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceSymbolOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentFormattingOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t\twantNil     = `{}`\n\t)\n\twantType := DocumentFormattingOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentFormattingOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentFormattingOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentFormattingOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentFormattingOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentFormattingOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentRangeFormattingOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := DocumentRangeFormattingOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentRangeFormattingOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentRangeFormattingOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentRangeFormattingOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentRangeFormattingOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentRangeFormattingOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDeclarationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := DeclarationOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DeclarationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DeclarationOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DeclarationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DeclarationOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DeclarationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDeclarationRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true,\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}],\"id\":\"1\"}`\n\t\twantNil     = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}]}`\n\t\twantInvalid = `{\"workDoneProgress\":false,\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"id\":\"0\"}`\n\t)\n\twantType := DeclarationRegistrationOptions{\n\t\tDeclarationOptions: DeclarationOptions{\n\t\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\t\tWorkDoneProgress: true,\n\t\t\t},\n\t\t},\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tStaticRegistrationOptions: StaticRegistrationOptions{\n\t\t\tID: \"1\",\n\t\t},\n\t}\n\twantTypeNil := DeclarationRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DeclarationRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DeclarationRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DeclarationRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDeclarationParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\"}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\"}`\n\t)\n\twantType := DeclarationParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t}\n\twantTypeNilAll := DeclarationParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DeclarationParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DeclarationParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DeclarationParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDefinitionOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := DefinitionOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DefinitionOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DefinitionOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DefinitionOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DefinitionOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DefinitionOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDefinitionParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\"}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\"}`\n\t)\n\twantType := DefinitionParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t}\n\twantTypeNilAll := DefinitionParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DefinitionParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DefinitionParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DefinitionParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTypeDefinitionOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := TypeDefinitionOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TypeDefinitionOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          TypeDefinitionOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TypeDefinitionOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             TypeDefinitionOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TypeDefinitionOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTypeDefinitionRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}],\"workDoneProgress\":true,\"id\":\"1\"}`\n\t\twantNil     = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"workDoneProgress\":false,\"id\":\"0\"}`\n\t)\n\twantType := TypeDefinitionRegistrationOptions{\n\t\tTypeDefinitionOptions: TypeDefinitionOptions{\n\t\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\t\tWorkDoneProgress: true,\n\t\t\t},\n\t\t},\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tStaticRegistrationOptions: StaticRegistrationOptions{\n\t\t\tID: \"1\",\n\t\t},\n\t}\n\twantTypeNil := TypeDefinitionRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TypeDefinitionRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TypeDefinitionRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TypeDefinitionRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTypeDefinitionParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\"}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\"}`\n\t)\n\twantType := TypeDefinitionParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t}\n\twantTypeNilAll := TypeDefinitionParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TypeDefinitionParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TypeDefinitionParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TypeDefinitionParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestImplementationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant       = `{\"workDoneProgress\":true}`\n\t\twantNilAll = `{}`\n\t)\n\twantType := ImplementationOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\twantTypeNilAll := ImplementationOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ImplementationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ImplementationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ImplementationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestImplementationRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}],\"workDoneProgress\":true,\"id\":\"1\"}`\n\t\twantNilAll  = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"workDoneProgress\":false,\"id\":\"0\"}`\n\t)\n\twantType := ImplementationRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tImplementationOptions: ImplementationOptions{\n\t\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\t\tWorkDoneProgress: true,\n\t\t\t},\n\t\t},\n\t\tStaticRegistrationOptions: StaticRegistrationOptions{\n\t\t\tID: \"1\",\n\t\t},\n\t}\n\twantTypeNilAll := ImplementationRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ImplementationRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ImplementationRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ImplementationRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestImplementationParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\"}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\"}`\n\t)\n\twantType := ImplementationParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t}\n\twantTypeNilAll := ImplementationParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ImplementationParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ImplementationParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ImplementationParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentColorOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := DocumentColorOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentColorOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          DocumentColorOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentColorOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             DocumentColorOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentColorOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentColorRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}],\"id\":\"1\",\"workDoneProgress\":true}`\n\t\twantNil     = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"id\":\"0\",\"workDoneProgress\":false}`\n\t)\n\twantType := DocumentColorRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tStaticRegistrationOptions: StaticRegistrationOptions{\n\t\t\tID: \"1\",\n\t\t},\n\t\tDocumentColorOptions: DocumentColorOptions{\n\t\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\t\tWorkDoneProgress: true,\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNil := DocumentColorRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentColorRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentColorRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentColorRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestPrepareSupportDefaultBehavior_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    PrepareSupportDefaultBehavior\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Identifier\",\n\t\t\tk:    PrepareSupportDefaultBehaviorIdentifier,\n\t\t\twant: \"Identifier\",\n\t\t},\n\t\t{\n\t\t\tname: \"UnknownKind\",\n\t\t\tk:    PrepareSupportDefaultBehavior(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"PrepareSupportDefaultBehavior.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestFoldingRangeOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"workDoneProgress\":true}`\n\t\twantNil     = `{}`\n\t\twantInvalid = `{\"workDoneProgress\":false}`\n\t)\n\twantType := FoldingRangeOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          FoldingRangeOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          FoldingRangeOptions{},\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             FoldingRangeOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             FoldingRangeOptions{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got FoldingRangeOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestFoldingRangeRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}],\"workDoneProgress\":true,\"id\":\"1\"}`\n\t\twantNil     = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"workDoneProgress\":false,\"id\":\"0\"}`\n\t)\n\twantType := FoldingRangeRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tFoldingRangeOptions: FoldingRangeOptions{\n\t\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\t\tWorkDoneProgress: true,\n\t\t\t},\n\t\t},\n\t\tStaticRegistrationOptions: StaticRegistrationOptions{\n\t\t\tID: \"1\",\n\t\t},\n\t}\n\twantTypeNil := FoldingRangeRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          FoldingRangeRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             FoldingRangeRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got FoldingRangeRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestInitializeResult(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"capabilities\":{\"textDocumentSync\":1,\"completionProvider\":{\"resolveProvider\":true,\"triggerCharacters\":[\"Tab\"]},\"hoverProvider\":true,\"signatureHelpProvider\":{\"triggerCharacters\":[\"C-K\"],\"retriggerCharacters\":[\".\"]},\"declarationProvider\":true,\"definitionProvider\":true,\"typeDefinitionProvider\":true,\"implementationProvider\":true,\"referencesProvider\":true,\"documentHighlightProvider\":true,\"documentSymbolProvider\":true,\"codeActionProvider\":true,\"codeLensProvider\":{\"resolveProvider\":true},\"documentLinkProvider\":{\"resolveProvider\":true},\"colorProvider\":true,\"workspaceSymbolProvider\":true,\"documentFormattingProvider\":true,\"documentRangeFormattingProvider\":true,\"documentOnTypeFormattingProvider\":{\"firstTriggerCharacter\":\".\",\"moreTriggerCharacter\":[\"f\"]},\"renameProvider\":true,\"foldingRangeProvider\":true,\"selectionRangeProvider\":true,\"executeCommandProvider\":{\"commands\":[\"test\",\"command\"]},\"callHierarchyProvider\":true,\"linkedEditingRangeProvider\":true,\"workspace\":{\"workspaceFolders\":{\"supported\":true,\"changeNotifications\":\"testNotifications\"},\"fileOperations\":{\"didCreate\":{\"filters\":[{\"scheme\":\"file\",\"pattern\":{\"glob\":\"*\",\"matches\":\"file\",\"options\":{\"ignoreCase\":true}}}]},\"willCreate\":{\"filters\":[{\"scheme\":\"file\",\"pattern\":{\"glob\":\"*\",\"matches\":\"folder\",\"options\":{\"ignoreCase\":true}}}]},\"didRename\":{\"filters\":[{\"scheme\":\"file\",\"pattern\":{\"glob\":\"*\",\"matches\":\"file\",\"options\":{\"ignoreCase\":true}}}]},\"willRename\":{\"filters\":[{\"scheme\":\"file\",\"pattern\":{\"glob\":\"*\",\"matches\":\"folder\",\"options\":{\"ignoreCase\":true}}}]},\"didDelete\":{\"filters\":[{\"scheme\":\"file\",\"pattern\":{\"glob\":\"*\",\"matches\":\"file\",\"options\":{\"ignoreCase\":true}}}]},\"willDelete\":{\"filters\":[{\"scheme\":\"file\",\"pattern\":{\"glob\":\"*\",\"matches\":\"folder\",\"options\":{\"ignoreCase\":true}}}]}}},\"monikerProvider\":true,\"experimental\":\"Awesome Experimentals\"},\"serverInfo\":{\"name\":\"testServer\",\"version\":\"v0.0.0\"}}`\n\t\twantNil = `{\"capabilities\":{}}`\n\t)\n\twantType := InitializeResult{\n\t\tCapabilities: ServerCapabilities{\n\t\t\tTextDocumentSync: float64(1),\n\t\t\tCompletionProvider: &CompletionOptions{\n\t\t\t\tResolveProvider:   true,\n\t\t\t\tTriggerCharacters: []string{\"Tab\"},\n\t\t\t},\n\t\t\tHoverProvider: true,\n\t\t\tSignatureHelpProvider: &SignatureHelpOptions{\n\t\t\t\tTriggerCharacters:   []string{\"C-K\"},\n\t\t\t\tRetriggerCharacters: []string{\".\"},\n\t\t\t},\n\t\t\tDeclarationProvider:       true,\n\t\t\tDefinitionProvider:        true,\n\t\t\tTypeDefinitionProvider:    true,\n\t\t\tImplementationProvider:    true,\n\t\t\tReferencesProvider:        true,\n\t\t\tDocumentHighlightProvider: true,\n\t\t\tDocumentSymbolProvider:    true,\n\t\t\tWorkspaceSymbolProvider:   true,\n\t\t\tCodeActionProvider:        true,\n\t\t\tCodeLensProvider: &CodeLensOptions{\n\t\t\t\tResolveProvider: true,\n\t\t\t},\n\t\t\tDocumentFormattingProvider:      true,\n\t\t\tDocumentRangeFormattingProvider: true,\n\t\t\tDocumentOnTypeFormattingProvider: &DocumentOnTypeFormattingOptions{\n\t\t\t\tFirstTriggerCharacter: \".\",\n\t\t\t\tMoreTriggerCharacter:  []string{\"f\"},\n\t\t\t},\n\t\t\tRenameProvider: true,\n\t\t\tDocumentLinkProvider: &DocumentLinkOptions{\n\t\t\t\tResolveProvider: true,\n\t\t\t},\n\t\t\tColorProvider:          true,\n\t\t\tFoldingRangeProvider:   true,\n\t\t\tSelectionRangeProvider: true,\n\t\t\tExecuteCommandProvider: &ExecuteCommandOptions{\n\t\t\t\tCommands: []string{\"test\", \"command\"},\n\t\t\t},\n\t\t\tWorkspace: &ServerCapabilitiesWorkspace{\n\t\t\t\tWorkspaceFolders: &ServerCapabilitiesWorkspaceFolders{\n\t\t\t\t\tSupported:           true,\n\t\t\t\t\tChangeNotifications: \"testNotifications\",\n\t\t\t\t},\n\t\t\t\tFileOperations: &ServerCapabilitiesWorkspaceFileOperations{\n\t\t\t\t\tDidCreate: &FileOperationRegistrationOptions{\n\t\t\t\t\t\tFilters: []FileOperationFilter{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tScheme: \"file\",\n\t\t\t\t\t\t\t\tPattern: FileOperationPattern{\n\t\t\t\t\t\t\t\t\tGlob:    \"*\",\n\t\t\t\t\t\t\t\t\tMatches: FileOperationPatternKindFile,\n\t\t\t\t\t\t\t\t\tOptions: FileOperationPatternOptions{\n\t\t\t\t\t\t\t\t\t\tIgnoreCase: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tWillCreate: &FileOperationRegistrationOptions{\n\t\t\t\t\t\tFilters: []FileOperationFilter{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tScheme: \"file\",\n\t\t\t\t\t\t\t\tPattern: FileOperationPattern{\n\t\t\t\t\t\t\t\t\tGlob:    \"*\",\n\t\t\t\t\t\t\t\t\tMatches: FileOperationPatternKindFolder,\n\t\t\t\t\t\t\t\t\tOptions: FileOperationPatternOptions{\n\t\t\t\t\t\t\t\t\t\tIgnoreCase: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tDidRename: &FileOperationRegistrationOptions{\n\t\t\t\t\t\tFilters: []FileOperationFilter{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tScheme: \"file\",\n\t\t\t\t\t\t\t\tPattern: FileOperationPattern{\n\t\t\t\t\t\t\t\t\tGlob:    \"*\",\n\t\t\t\t\t\t\t\t\tMatches: FileOperationPatternKindFile,\n\t\t\t\t\t\t\t\t\tOptions: FileOperationPatternOptions{\n\t\t\t\t\t\t\t\t\t\tIgnoreCase: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tWillRename: &FileOperationRegistrationOptions{\n\t\t\t\t\t\tFilters: []FileOperationFilter{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tScheme: \"file\",\n\t\t\t\t\t\t\t\tPattern: FileOperationPattern{\n\t\t\t\t\t\t\t\t\tGlob:    \"*\",\n\t\t\t\t\t\t\t\t\tMatches: FileOperationPatternKindFolder,\n\t\t\t\t\t\t\t\t\tOptions: FileOperationPatternOptions{\n\t\t\t\t\t\t\t\t\t\tIgnoreCase: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tDidDelete: &FileOperationRegistrationOptions{\n\t\t\t\t\t\tFilters: []FileOperationFilter{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tScheme: \"file\",\n\t\t\t\t\t\t\t\tPattern: FileOperationPattern{\n\t\t\t\t\t\t\t\t\tGlob:    \"*\",\n\t\t\t\t\t\t\t\t\tMatches: FileOperationPatternKindFile,\n\t\t\t\t\t\t\t\t\tOptions: FileOperationPatternOptions{\n\t\t\t\t\t\t\t\t\t\tIgnoreCase: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tWillDelete: &FileOperationRegistrationOptions{\n\t\t\t\t\t\tFilters: []FileOperationFilter{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tScheme: \"file\",\n\t\t\t\t\t\t\t\tPattern: FileOperationPattern{\n\t\t\t\t\t\t\t\t\tGlob:    \"*\",\n\t\t\t\t\t\t\t\t\tMatches: FileOperationPatternKindFolder,\n\t\t\t\t\t\t\t\t\tOptions: FileOperationPatternOptions{\n\t\t\t\t\t\t\t\t\t\tIgnoreCase: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tLinkedEditingRangeProvider: true,\n\t\t\tCallHierarchyProvider:      true,\n\t\t\tSemanticTokensProvider:     nil,\n\t\t\tMonikerProvider:            true,\n\t\t\tExperimental:               \"Awesome Experimentals\",\n\t\t},\n\t\tServerInfo: &ServerInfo{\n\t\t\tName:    \"testServer\",\n\t\t\tVersion: \"v0.0.0\",\n\t\t},\n\t}\n\twantTypeNil := InitializeResult{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          InitializeResult\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Logf(\"got: %s\", string(got))\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             InitializeResult\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got InitializeResult\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\t// cmpOpts := cmpopts.IgnoreFields(ServerCapabilities{}, \"SelectionRangeProvider\") // ignore SelectionRangeProvider field but assert below\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\t// if srp := got.Capabilities.SelectionRangeProvider; srp != nil {\n\t\t\t\t// \tswitch srp := srp.(type) {\n\t\t\t\t// \tcase bool: // EnableSelectionRange\n\t\t\t\t// \t\tif diff := cmp.Diff(EnableSelectionRange(srp), enableSelectionRange); (diff != \"\") != tt.wantErr {\n\t\t\t\t// \t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t// \t\t}\n\t\t\t\t// \tdefault:\n\t\t\t\t// \t\tt.Fatalf(\"srp type is %[1]T, not bool: %#[1]v\\n\", srp)\n\t\t\t\t// \t}\n\t\t\t\t// }\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestInitializeError(t *testing.T) {\n\tt.Parallel()\n\n\tconst want = `{\"retry\":true}`\n\twantType := InitializeError{\n\t\tRetry: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          InitializeError\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             InitializeError\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got InitializeError\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestShowDocumentParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"uri\":\"file:///path/to/basic.go\",\"external\":true,\"takeFocus\":true,\"selection\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}}}`\n\t\twantNil = `{\"uri\":\"file:///path/to/basic.go\"}`\n\t)\n\twantType := ShowDocumentParams{\n\t\tURI:       uri.File(\"/path/to/basic.go\"),\n\t\tExternal:  true,\n\t\tTakeFocus: true,\n\t\tSelection: &Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 4,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 10,\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := ShowDocumentParams{\n\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ShowDocumentParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ShowDocumentParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ShowDocumentParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestShowDocumentResult(t *testing.T) {\n\tt.Parallel()\n\n\tconst want = `{\"success\":true}`\n\twantType := ShowDocumentResult{\n\t\tSuccess: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ShowDocumentResult\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ShowDocumentResult\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ShowDocumentResult\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentSyncKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    TextDocumentSyncKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"NoneKind\",\n\t\t\tk:    TextDocumentSyncKindNone,\n\t\t\twant: \"None\",\n\t\t},\n\t\t{\n\t\t\tname: \"FullKind\",\n\t\t\tk:    TextDocumentSyncKindFull,\n\t\t\twant: \"Full\",\n\t\t},\n\t\t{\n\t\t\tname: \"IncrementalKind\",\n\t\t\tk:    TextDocumentSyncKindIncremental,\n\t\t\twant: \"Incremental\",\n\t\t},\n\t\t{\n\t\t\tname: \"UnknownKind\",\n\t\t\tk:    TextDocumentSyncKind(99),\n\t\t\twant: \"99\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"TextDocumentSyncKind.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestReferencesOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst want = `{\"workDoneProgress\":true}`\n\twantType := ReferencesOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ReferencesOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ReferencesOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ReferencesOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeActionOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"codeActionKinds\":[\"quickfix\",\"refactor\"],\"resolveProvider\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := CodeActionOptions{\n\t\tCodeActionKinds: []CodeActionKind{\n\t\t\tQuickFix,\n\t\t\tRefactor,\n\t\t},\n\t\tResolveProvider: true,\n\t}\n\twantTypeNil := CodeActionOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeActionOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeActionOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeActionOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRenameOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"prepareProvider\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := RenameOptions{\n\t\tPrepareProvider: true,\n\t}\n\twantTypeNil := RenameOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RenameOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RenameOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RenameOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSaveOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"includeText\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := SaveOptions{\n\t\tIncludeText: true,\n\t}\n\twantTypeNil := SaveOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SaveOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SaveOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SaveOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentSyncOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"openClose\":true,\"change\":1,\"willSave\":true,\"willSaveWaitUntil\":true,\"save\":{\"includeText\":true}}`\n\t\twantNil = `{}`\n\t)\n\twantType := TextDocumentSyncOptions{\n\t\tOpenClose:         true,\n\t\tChange:            TextDocumentSyncKindFull,\n\t\tWillSave:          true,\n\t\tWillSaveWaitUntil: true,\n\t\tSave: &SaveOptions{\n\t\t\tIncludeText: true,\n\t\t},\n\t}\n\twantTypeNil := TextDocumentSyncOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentSyncOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentSyncOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentSyncOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestHoverOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"workDoneProgress\":true}`\n\t\twantNil = `{}`\n\t)\n\twantType := HoverOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: true,\n\t\t},\n\t}\n\twantTypeNil := HoverOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          HoverOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             HoverOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got HoverOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestStaticRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"id\":\"testID\"}`\n\t\twantNil = `{}`\n\t)\n\twantType := StaticRegistrationOptions{\n\t\tID: \"testID\",\n\t}\n\twantTypeNil := StaticRegistrationOptions{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          StaticRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             StaticRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got StaticRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentLinkRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant    = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*\"}],\"resolveProvider\":true}`\n\t\twantNil = `{\"documentSelector\":[]}`\n\t)\n\twantType := DocumentLinkRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  `*`,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tResolveProvider: true,\n\t}\n\twantTypeNilAll := DocumentLinkRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentLinkRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentLinkRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentLinkRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestInitializedParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst want = `{}`\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          InitializedParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          InitializedParams{},\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             InitializedParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             InitializedParams{},\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got InitializedParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/handler.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"encoding/json\"\n\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n\t\"github.com/a-h/templ/lsp/xcontext\"\n)\n\n// CancelHandler handler of cancelling.\nfunc CancelHandler(handler jsonrpc2.Handler) jsonrpc2.Handler {\n\thandler, canceller := jsonrpc2.CancelHandler(handler)\n\n\th := func(ctx context.Context, reply jsonrpc2.Replier, req jsonrpc2.Request) error {\n\t\tif req.Method() != MethodCancelRequest {\n\t\t\t// TODO(iancottrell): See if we can generate a reply for the request to be cancelled\n\t\t\t// at the point of cancellation rather than waiting for gopls to naturally reply.\n\t\t\t// To do that, we need to keep track of whether a reply has been sent already and\n\t\t\t// be careful about racing between the two paths.\n\t\t\t// TODO(iancottrell): Add a test that watches the stream and verifies the response\n\t\t\t// for the cancelled request flows.\n\t\t\treply := func(ctx context.Context, resp any, err error) error {\n\t\t\t\t// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#cancelRequest\n\t\t\t\tif ctx.Err() != nil && err == nil {\n\t\t\t\t\terr = ErrRequestCancelled\n\t\t\t\t}\n\t\t\t\tctx = xcontext.Detach(ctx)\n\n\t\t\t\treturn reply(ctx, resp, err)\n\t\t\t}\n\n\t\t\treturn handler(ctx, reply, req)\n\t\t}\n\n\t\tvar params CancelParams\n\t\tif err := json.Unmarshal(req.Params(), &params); err != nil {\n\t\t\treturn replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tswitch id := params.ID.(type) {\n\t\tcase int32:\n\t\t\tcanceller(jsonrpc2.NewNumberID(id))\n\t\tcase string:\n\t\t\tcanceller(jsonrpc2.NewStringID(id))\n\t\tdefault:\n\t\t\treturn replyParseError(ctx, reply, fmt.Errorf(\"request ID %v malformed\", id))\n\t\t}\n\n\t\treturn reply(ctx, nil, nil)\n\t}\n\n\treturn h\n}\n\n// Handlers default jsonrpc2.Handler.\nfunc Handlers(handler jsonrpc2.Handler) jsonrpc2.Handler {\n\treturn CancelHandler(\n\t\tjsonrpc2.AsyncHandler(\n\t\t\tjsonrpc2.ReplyHandler(handler),\n\t\t),\n\t)\n}\n\n// Call calls method to params and result.\nfunc Call(ctx context.Context, conn jsonrpc2.Conn, method string, params, result any) error {\n\tid, err := conn.Call(ctx, method, params, result)\n\tif ctx.Err() != nil {\n\t\tnotifyCancel(ctx, conn, id)\n\t}\n\n\treturn err\n}\n\nfunc notifyCancel(ctx context.Context, conn jsonrpc2.Conn, id jsonrpc2.ID) {\n\tctx = xcontext.Detach(ctx)\n\t// Note that only *jsonrpc2.ID implements json.Marshaler.\n\t_ = conn.Notify(ctx, MethodCancelRequest, &CancelParams{ID: &id})\n}\n\nfunc replyParseError(ctx context.Context, reply jsonrpc2.Replier, err error) error {\n\treturn reply(ctx, nil, fmt.Errorf(\"%s: %w\", jsonrpc2.ErrParse, err))\n}\n"
  },
  {
    "path": "lsp/protocol/language.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"strconv\"\n\n\t\"encoding/json\"\n)\n\n// CompletionParams params of Completion request.\ntype CompletionParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// Context is the completion context. This is only available if the client specifies\n\t// to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`\n\tContext *CompletionContext `json:\"context,omitempty\"`\n}\n\n// CompletionTriggerKind how a completion was triggered.\ntype CompletionTriggerKind float64\n\nconst (\n\t// CompletionTriggerKindInvoked completion was triggered by typing an identifier (24x7 code\n\t// complete), manual invocation (e.g Ctrl+Space) or via API.\n\tCompletionTriggerKindInvoked CompletionTriggerKind = 1\n\n\t// CompletionTriggerKindTriggerCharacter completion was triggered by a trigger character specified by\n\t// the `triggerCharacters` properties of the `CompletionRegistrationOptions`.\n\tCompletionTriggerKindTriggerCharacter CompletionTriggerKind = 2\n\n\t// CompletionTriggerKindTriggerForIncompleteCompletions completion was re-triggered as the current completion list is incomplete.\n\tCompletionTriggerKindTriggerForIncompleteCompletions CompletionTriggerKind = 3\n)\n\n// String implements fmt.Stringer.\nfunc (k CompletionTriggerKind) String() string {\n\tswitch k {\n\tcase CompletionTriggerKindInvoked:\n\t\treturn \"Invoked\"\n\tcase CompletionTriggerKindTriggerCharacter:\n\t\treturn \"TriggerCharacter\"\n\tcase CompletionTriggerKindTriggerForIncompleteCompletions:\n\t\treturn \"TriggerForIncompleteCompletions\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// CompletionContext contains additional information about the context in which a completion request is triggered.\ntype CompletionContext struct {\n\t// TriggerCharacter is the trigger character (a single character) that has trigger code complete.\n\t// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`\n\tTriggerCharacter string `json:\"triggerCharacter,omitempty\"`\n\n\t// TriggerKind how the completion was triggered.\n\tTriggerKind CompletionTriggerKind `json:\"triggerKind\"`\n}\n\n// CompletionList represents a collection of [completion items](#CompletionItem) to be presented\n// in the editor.\ntype CompletionList struct {\n\t// IsIncomplete this list it not complete. Further typing should result in recomputing\n\t// this list.\n\tIsIncomplete bool `json:\"isIncomplete\"`\n\n\t// Items is the completion items.\n\tItems []CompletionItem `json:\"items\"`\n}\n\n// InsertTextFormat defines whether the insert text in a completion item should be interpreted as\n// plain text or a snippet.\ntype InsertTextFormat float64\n\nconst (\n\t// InsertTextFormatPlainText is the primary text to be inserted is treated as a plain string.\n\tInsertTextFormatPlainText InsertTextFormat = 1\n\n\t// InsertTextFormatSnippet is the primary text to be inserted is treated as a snippet.\n\t//\n\t// A snippet can define tab stops and placeholders with `$1`, `$2`\n\t// and `${3:foo}`. `$0` defines the final tab stop, it defaults to\n\t// the end of the snippet. Placeholders with equal identifiers are linked,\n\t// that is typing in one will update others too.\n\tInsertTextFormatSnippet InsertTextFormat = 2\n)\n\n// String implements fmt.Stringer.\nfunc (tf InsertTextFormat) String() string {\n\tswitch tf {\n\tcase InsertTextFormatPlainText:\n\t\treturn \"PlainText\"\n\tcase InsertTextFormatSnippet:\n\t\treturn \"Snippet\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(tf), 'f', -10, 64)\n\t}\n}\n\n// InsertReplaceEdit is a special text edit to provide an insert and a replace operation.\n//\n// @since 3.16.0.\ntype InsertReplaceEdit struct {\n\t// NewText is the string to be inserted.\n\tNewText string `json:\"newText\"`\n\n\t// Insert is the range if the insert is requested.\n\tInsert Range `json:\"insert\"`\n\n\t// Replace is the range if the replace is requested.\n\tReplace Range `json:\"replace\"`\n}\n\n// InsertTextMode how whitespace and indentation is handled during completion\n// item insertion.\n//\n// @since 3.16.0.\ntype InsertTextMode float64\n\nconst (\n\t// AsIs is the insertion or replace strings is taken as it is. If the\n\t// value is multi line the lines below the cursor will be\n\t// inserted using the indentation defined in the string value.\n\t// The client will not apply any kind of adjustments to the\n\t// string.\n\tInsertTextModeAsIs InsertTextMode = 1\n\n\t// AdjustIndentation is the editor adjusts leading whitespace of new lines so that\n\t// they match the indentation up to the cursor of the line for\n\t// which the item is accepted.\n\t//\n\t// Consider a line like this: <2tabs><cursor><3tabs>foo. Accepting a\n\t// multi line completion item is indented using 2 tabs and all\n\t// following lines inserted will be indented using 2 tabs as well.\n\tInsertTextModeAdjustIndentation InsertTextMode = 2\n)\n\n// String returns a string representation of the InsertTextMode.\nfunc (k InsertTextMode) String() string {\n\tswitch k {\n\tcase InsertTextModeAsIs:\n\t\treturn \"AsIs\"\n\tcase InsertTextModeAdjustIndentation:\n\t\treturn \"AdjustIndentation\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// CompletionItem item of CompletionList.\ntype CompletionItem struct {\n\t// AdditionalTextEdits an optional array of additional text edits that are applied when\n\t// selecting this completion. Edits must not overlap (including the same insert position)\n\t// with the main edit nor with themselves.\n\t//\n\t// Additional text edits should be used to change text unrelated to the current cursor position\n\t// (for example adding an import statement at the top of the file if the completion item will\n\t// insert an unqualified type).\n\tAdditionalTextEdits []TextEdit `json:\"additionalTextEdits,omitempty\"`\n\n\t// Command an optional command that is executed *after* inserting this completion. *Note* that\n\t// additional modifications to the current document should be described with the\n\t// additionalTextEdits-property.\n\tCommand *Command `json:\"command,omitempty\"`\n\n\t// CommitCharacters an optional set of characters that when pressed while this completion is active will accept it first and\n\t// then type that character. *Note* that all commit characters should have `length=1` and that superfluous\n\t// characters will be ignored.\n\tCommitCharacters []string `json:\"commitCharacters,omitempty\"`\n\n\t// Tags is the tag for this completion item.\n\t//\n\t// @since 3.15.0.\n\tTags []CompletionItemTag `json:\"tags,omitempty\"`\n\n\t// Data an data entry field that is preserved on a completion item between\n\t// a completion and a completion resolve request.\n\tData any `json:\"data,omitempty\"`\n\n\t// Deprecated indicates if this item is deprecated.\n\tDeprecated bool `json:\"deprecated,omitempty\"`\n\n\t// Detail a human-readable string with additional information\n\t// about this item, like type or symbol information.\n\tDetail string `json:\"detail,omitempty\"`\n\n\t// Documentation a human-readable string that represents a doc-comment.\n\tDocumentation any `json:\"documentation,omitempty\"`\n\n\t// FilterText a string that should be used when filtering a set of\n\t// completion items. When `falsy` the label is used.\n\tFilterText string `json:\"filterText,omitempty\"`\n\n\t// InsertText a string that should be inserted into a document when selecting\n\t// this completion. When `falsy` the label is used.\n\t//\n\t// The `insertText` is subject to interpretation by the client side.\n\t// Some tools might not take the string literally. For example\n\t// VS Code when code complete is requested in this example `con<cursor position>`\n\t// and a completion item with an `insertText` of `console` is provided it\n\t// will only insert `sole`. Therefore it is recommended to use `textEdit` instead\n\t// since it avoids additional client side interpretation.\n\tInsertText string `json:\"insertText,omitempty\"`\n\n\t// InsertTextFormat is the format of the insert text. The format applies to both the `insertText` property\n\t// and the `newText` property of a provided `textEdit`.\n\tInsertTextFormat InsertTextFormat `json:\"insertTextFormat,omitempty\"`\n\n\t// InsertTextMode how whitespace and indentation is handled during completion\n\t// item insertion. If not provided the client's default value depends on\n\t// the `textDocument.completion.insertTextMode` client capability.\n\t//\n\t// @since 3.16.0.\n\tInsertTextMode InsertTextMode `json:\"insertTextMode,omitempty\"`\n\n\t// Kind is the kind of this completion item. Based of the kind\n\t// an icon is chosen by the editor.\n\tKind CompletionItemKind `json:\"kind,omitempty\"`\n\n\t// Label is the label of this completion item. By default\n\t// also the text that is inserted when selecting\n\t// this completion.\n\tLabel string `json:\"label\"`\n\n\t// Preselect select this item when showing.\n\t//\n\t// *Note* that only one completion item can be selected and that the\n\t// tool / client decides which item that is. The rule is that the *first*\n\t// item of those that match best is selected.\n\tPreselect bool `json:\"preselect,omitempty\"`\n\n\t// SortText a string that should be used when comparing this item\n\t// with other items. When `falsy` the label is used.\n\tSortText string `json:\"sortText,omitempty\"`\n\n\t// TextEdit an edit which is applied to a document when selecting this completion. When an edit is provided the value of\n\t// `insertText` is ignored.\n\t//\n\t// NOTE: The range of the edit must be a single line range and it must contain the position at which completion\n\t// has been requested.\n\t//\n\t// Most editors support two different operations when accepting a completion\n\t// item. One is to insert a completion text and the other is to replace an\n\t// existing text with a completion text. Since this can usually not be\n\t// predetermined by a server it can report both ranges. Clients need to\n\t// signal support for `InsertReplaceEdits` via the\n\t// \"textDocument.completion.insertReplaceSupport\" client capability\n\t// property.\n\t//\n\t// NOTE 1: The text edit's range as well as both ranges from an insert\n\t// replace edit must be a [single line] and they must contain the position\n\t// at which completion has been requested.\n\t//\n\t// NOTE 2: If an \"InsertReplaceEdit\" is returned the edit's insert range\n\t// must be a prefix of the edit's replace range, that means it must be\n\t// contained and starting at the same position.\n\t//\n\t// @since 3.16.0 additional type \"InsertReplaceEdit\".\n\tTextEdit *TextEditOrInsertReplaceEdit `json:\"textEdit,omitempty\"` // *TextEdit | *InsertReplaceEdit\n}\n\ntype TextEditOrInsertReplaceEdit struct {\n\tTextEdit          *TextEdit\n\tInsertReplaceEdit *InsertReplaceEdit\n}\n\nfunc (t *TextEditOrInsertReplaceEdit) MarshalJSON() ([]byte, error) {\n\tif t.TextEdit != nil {\n\t\treturn json.Marshal(t.TextEdit)\n\t}\n\treturn json.Marshal(t.InsertReplaceEdit)\n}\n\ntype textEditAndInsertReplaceEdit struct {\n\t// NewText is in both types.\n\tNewText string `json:\"newText\"`\n\n\t// Range is only present in TextEdit.\n\tRange *Range `json:\"range\"`\n\n\t// Insert is only present in InsertReplaceEdit.\n\tInsert Range `json:\"insert\"`\n\t// Replace is only present in InsertReplaceEdit.\n\tReplace Range `json:\"replace\"`\n}\n\nfunc (t *TextEditOrInsertReplaceEdit) UnmarshalJSON(data []byte) error {\n\tvar teaire textEditAndInsertReplaceEdit\n\tif err := json.Unmarshal(data, &teaire); err != nil {\n\t\treturn err\n\t}\n\tif teaire.Range != nil {\n\t\tt.TextEdit = &TextEdit{\n\t\t\tNewText: teaire.NewText,\n\t\t\tRange:   *teaire.Range,\n\t\t}\n\t\treturn nil\n\t}\n\tt.InsertReplaceEdit = &InsertReplaceEdit{\n\t\tNewText: teaire.NewText,\n\t\tInsert:  teaire.Insert,\n\t\tReplace: teaire.Replace,\n\t}\n\treturn nil\n}\n\n// CompletionItemKind is 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.\ntype CompletionItemKind float64\n\nconst (\n\t// CompletionItemKindText text completion kind.\n\tCompletionItemKindText CompletionItemKind = 1\n\t// CompletionItemKindMethod method completion kind.\n\tCompletionItemKindMethod CompletionItemKind = 2\n\t// CompletionItemKindFunction function completion kind.\n\tCompletionItemKindFunction CompletionItemKind = 3\n\t// CompletionItemKindConstructor constructor completion kind.\n\tCompletionItemKindConstructor CompletionItemKind = 4\n\t// CompletionItemKindField field completion kind.\n\tCompletionItemKindField CompletionItemKind = 5\n\t// CompletionItemKindVariable variable completion kind.\n\tCompletionItemKindVariable CompletionItemKind = 6\n\t// CompletionItemKindClass class completion kind.\n\tCompletionItemKindClass CompletionItemKind = 7\n\t// CompletionItemKindInterface interface completion kind.\n\tCompletionItemKindInterface CompletionItemKind = 8\n\t// CompletionItemKindModule module completion kind.\n\tCompletionItemKindModule CompletionItemKind = 9\n\t// CompletionItemKindProperty property completion kind.\n\tCompletionItemKindProperty CompletionItemKind = 10\n\t// CompletionItemKindUnit unit completion kind.\n\tCompletionItemKindUnit CompletionItemKind = 11\n\t// CompletionItemKindValue value completion kind.\n\tCompletionItemKindValue CompletionItemKind = 12\n\t// CompletionItemKindEnum enum completion kind.\n\tCompletionItemKindEnum CompletionItemKind = 13\n\t// CompletionItemKindKeyword keyword completion kind.\n\tCompletionItemKindKeyword CompletionItemKind = 14\n\t// CompletionItemKindSnippet snippet completion kind.\n\tCompletionItemKindSnippet CompletionItemKind = 15\n\t// CompletionItemKindColor color completion kind.\n\tCompletionItemKindColor CompletionItemKind = 16\n\t// CompletionItemKindFile file completion kind.\n\tCompletionItemKindFile CompletionItemKind = 17\n\t// CompletionItemKindReference reference completion kind.\n\tCompletionItemKindReference CompletionItemKind = 18\n\t// CompletionItemKindFolder folder completion kind.\n\tCompletionItemKindFolder CompletionItemKind = 19\n\t// CompletionItemKindEnumMember enum member completion kind.\n\tCompletionItemKindEnumMember CompletionItemKind = 20\n\t// CompletionItemKindConstant constant completion kind.\n\tCompletionItemKindConstant CompletionItemKind = 21\n\t// CompletionItemKindStruct struct completion kind.\n\tCompletionItemKindStruct CompletionItemKind = 22\n\t// CompletionItemKindEvent event completion kind.\n\tCompletionItemKindEvent CompletionItemKind = 23\n\t// CompletionItemKindOperator operator completion kind.\n\tCompletionItemKindOperator CompletionItemKind = 24\n\t// CompletionItemKindTypeParameter type parameter completion kind.\n\tCompletionItemKindTypeParameter CompletionItemKind = 25\n)\n\n// String implements fmt.Stringer.\n//\n//nolint:cyclop\nfunc (k CompletionItemKind) String() string {\n\tswitch k {\n\tcase CompletionItemKindText:\n\t\treturn \"Text\"\n\tcase CompletionItemKindMethod:\n\t\treturn \"Method\"\n\tcase CompletionItemKindFunction:\n\t\treturn \"Function\"\n\tcase CompletionItemKindConstructor:\n\t\treturn \"Constructor\"\n\tcase CompletionItemKindField:\n\t\treturn \"Field\"\n\tcase CompletionItemKindVariable:\n\t\treturn \"Variable\"\n\tcase CompletionItemKindClass:\n\t\treturn \"Class\"\n\tcase CompletionItemKindInterface:\n\t\treturn \"Interface\"\n\tcase CompletionItemKindModule:\n\t\treturn \"Module\"\n\tcase CompletionItemKindProperty:\n\t\treturn \"Property\"\n\tcase CompletionItemKindUnit:\n\t\treturn \"Unit\"\n\tcase CompletionItemKindValue:\n\t\treturn \"Value\"\n\tcase CompletionItemKindEnum:\n\t\treturn \"Enum\"\n\tcase CompletionItemKindKeyword:\n\t\treturn \"Keyword\"\n\tcase CompletionItemKindSnippet:\n\t\treturn \"Snippet\"\n\tcase CompletionItemKindColor:\n\t\treturn \"Color\"\n\tcase CompletionItemKindFile:\n\t\treturn \"File\"\n\tcase CompletionItemKindReference:\n\t\treturn \"Reference\"\n\tcase CompletionItemKindFolder:\n\t\treturn \"Folder\"\n\tcase CompletionItemKindEnumMember:\n\t\treturn \"EnumMember\"\n\tcase CompletionItemKindConstant:\n\t\treturn \"Constant\"\n\tcase CompletionItemKindStruct:\n\t\treturn \"Struct\"\n\tcase CompletionItemKindEvent:\n\t\treturn \"Event\"\n\tcase CompletionItemKindOperator:\n\t\treturn \"Operator\"\n\tcase CompletionItemKindTypeParameter:\n\t\treturn \"TypeParameter\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// CompletionItemTag completion item tags are extra annotations that tweak the rendering of a completion\n// item.\n//\n// @since 3.15.0.\ntype CompletionItemTag float64\n\n// list of CompletionItemTag.\nconst (\n\t// CompletionItemTagDeprecated is the render a completion as obsolete, usually using a strike-out.\n\tCompletionItemTagDeprecated CompletionItemTag = 1\n)\n\n// String returns a string representation of the type.\nfunc (c CompletionItemTag) String() string {\n\tswitch c {\n\tcase CompletionItemTagDeprecated:\n\t\treturn \"Deprecated\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(c), 'f', -10, 64)\n\t}\n}\n\n// CompletionRegistrationOptions CompletionRegistration options.\ntype CompletionRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// TriggerCharacters most tools trigger completion request automatically without explicitly requesting\n\t// it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user\n\t// starts to type an identifier. For example if the user types `c` in a JavaScript file\n\t// code complete will automatically pop up present `console` besides others as a\n\t// completion item. Characters that make up identifiers don't need to be listed here.\n\t//\n\t// If code complete should automatically be trigger on characters not being valid inside\n\t// an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.\n\tTriggerCharacters []string `json:\"triggerCharacters,omitempty\"`\n\n\t// ResolveProvider is the server provides support to resolve additional\n\t// information for a completion item.\n\tResolveProvider bool `json:\"resolveProvider,omitempty\"`\n}\n\n// HoverParams params of Hover request.\n//\n// @since 3.15.0.\ntype HoverParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n}\n\n// Hover is the result of a hover request.\ntype Hover struct {\n\t// Contents is the hover's content\n\tContents MarkupContent `json:\"contents\"`\n\n\t// Range an optional range is a range inside a text document\n\t// that is used to visualize a hover, e.g. by changing the background color.\n\tRange *Range `json:\"range,omitempty\"`\n}\n\n// SignatureHelpParams params of SignatureHelp request.\n//\n// @since 3.15.0.\ntype SignatureHelpParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\n\t// context is the signature help context.\n\t//\n\t// This is only available if the client specifies to send this using the\n\t// client capability `textDocument.signatureHelp.contextSupport === true`.\n\t//\n\t// @since 3.15.0.\n\tContext *SignatureHelpContext `json:\"context,omitempty\"`\n}\n\n// SignatureHelpTriggerKind is the how a signature help was triggered.\n//\n// @since 3.15.0.\ntype SignatureHelpTriggerKind float64\n\n// list of SignatureHelpTriggerKind.\nconst (\n\t// SignatureHelpTriggerKindInvoked is the signature help was invoked manually by the user or by a command.\n\tSignatureHelpTriggerKindInvoked SignatureHelpTriggerKind = 1\n\n\t// SignatureHelpTriggerKindTriggerCharacter is the signature help was triggered by a trigger character.\n\tSignatureHelpTriggerKindTriggerCharacter SignatureHelpTriggerKind = 2\n\n\t// SignatureHelpTriggerKindContentChange is the signature help was triggered by the cursor moving or\n\t// by the document content changing.\n\tSignatureHelpTriggerKindContentChange SignatureHelpTriggerKind = 3\n)\n\n// String returns a string representation of the type.\nfunc (s SignatureHelpTriggerKind) String() string {\n\tswitch s {\n\tcase SignatureHelpTriggerKindInvoked:\n\t\treturn \"Invoked\"\n\tcase SignatureHelpTriggerKindTriggerCharacter:\n\t\treturn \"TriggerCharacter\"\n\tcase SignatureHelpTriggerKindContentChange:\n\t\treturn \"ContentChange\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(s), 'f', -10, 64)\n\t}\n}\n\n// SignatureHelpContext is the additional information about the context in which a\n// signature help request was triggered.\n//\n// @since 3.15.0.\ntype SignatureHelpContext struct {\n\t// TriggerKind is the action that caused signature help to be triggered.\n\tTriggerKind SignatureHelpTriggerKind `json:\"triggerKind\"`\n\n\t// Character that caused signature help to be triggered.\n\t//\n\t// This is undefined when\n\t//  TriggerKind != SignatureHelpTriggerKindTriggerCharacter\n\tTriggerCharacter string `json:\"triggerCharacter,omitempty\"`\n\n\t// IsRetrigger is the `true` if signature help was already showing when it was triggered.\n\t//\n\t// Retriggers occur when the signature help is already active and can be\n\t// caused by actions such as typing a trigger character, a cursor move,\n\t// or document content changes.\n\tIsRetrigger bool `json:\"isRetrigger\"`\n\n\t// ActiveSignatureHelp is the currently active SignatureHelp.\n\t//\n\t// The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field\n\t// updated based on the user navigating through available signatures.\n\tActiveSignatureHelp *SignatureHelp `json:\"activeSignatureHelp,omitempty\"`\n}\n\n// SignatureHelp signature help represents the signature of something\n// callable. There can be multiple signature but only one\n// active and only one active parameter.\ntype SignatureHelp struct {\n\t// Signatures one or more signatures.\n\tSignatures []SignatureInformation `json:\"signatures\"`\n\n\t// ActiveParameter is the active parameter of the active signature. If omitted or the value\n\t// lies outside the range of `signatures[activeSignature].parameters`\n\t// defaults to 0 if the active signature has parameters. If\n\t// the active signature has no parameters it is ignored.\n\t// In future version of the protocol this property might become\n\t// mandatory to better express the active parameter if the\n\t// active signature does have any.\n\tActiveParameter uint32 `json:\"activeParameter,omitempty\"`\n\n\t// ActiveSignature is the active signature. If omitted or the value lies outside the\n\t// range of `signatures` the value defaults to zero or is ignored if\n\t// `signatures.length === 0`. Whenever possible implementors should\n\t// make an active decision about the active signature and shouldn't\n\t// rely on a default value.\n\t// In future version of the protocol this property might become\n\t// mandatory to better express this.\n\tActiveSignature uint32 `json:\"activeSignature,omitempty\"`\n}\n\n// SignatureInformation is the client supports the following `SignatureInformation`\n// specific properties.\ntype SignatureInformation struct {\n\t// Label is the label of this signature. Will be shown in\n\t// the UI.\n\t//\n\t// @since 3.16.0.\n\tLabel string `json:\"label\"`\n\n\t// Documentation is the human-readable doc-comment of this signature. Will be shown\n\t// in the UI but can be omitted.\n\t//\n\t// @since 3.16.0.\n\tDocumentation any `json:\"documentation,omitempty\"` // string | *MarkupContent\n\n\t// Parameters is the parameters of this signature.\n\t//\n\t// @since 3.16.0.\n\tParameters []ParameterInformation `json:\"parameters,omitempty\"`\n\n\t// ActiveParameterSupport is the client supports the `activeParameter` property on\n\t// `SignatureInformation` literal.\n\t//\n\t// @since 3.16.0.\n\tActiveParameter uint32 `json:\"activeParameter,omitempty\"`\n}\n\n// ParameterInformation represents a parameter of a callable-signature. A parameter can\n// have a label and a doc-comment.\ntype ParameterInformation struct {\n\t// Label is the label of this parameter information.\n\t//\n\t// Either a string or an inclusive start and exclusive end offsets within its containing\n\t// signature label. (see SignatureInformation.label). The offsets are based on a UTF-16\n\t// string representation as \"Position\" and \"Range\" does.\n\t//\n\t// *Note*: a label of type string should be a substring of its containing signature label.\n\t// Its intended use case is to highlight the parameter label part in the \"SignatureInformation.label\".\n\tLabel string `json:\"label\"` // string | [uint32, uint32]\n\n\t// Documentation is the human-readable doc-comment of this parameter. Will be shown\n\t// in the UI but can be omitted.\n\tDocumentation any `json:\"documentation,omitempty\"` // string | MarkupContent\n}\n\n// SignatureHelpRegistrationOptions SignatureHelp Registration options.\ntype SignatureHelpRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// TriggerCharacters is the characters that trigger signature help\n\t// automatically.\n\tTriggerCharacters []string `json:\"triggerCharacters,omitempty\"`\n}\n\n// ReferenceParams params of References request.\n//\n// @since 3.15.0.\ntype ReferenceParams struct {\n\tTextDocumentPositionParams\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// Context is the ReferenceParams context.\n\tContext ReferenceContext `json:\"context\"`\n}\n\n// ReferenceContext context of ReferenceParams.\ntype ReferenceContext struct {\n\t// IncludeDeclaration include the declaration of the current symbol.\n\tIncludeDeclaration bool `json:\"includeDeclaration\"`\n}\n\n// DocumentHighlight 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.\ntype DocumentHighlight struct {\n\t// Range is the range this highlight applies to.\n\tRange Range `json:\"range\"`\n\n\t// Kind is the highlight kind, default is DocumentHighlightKind.Text.\n\tKind DocumentHighlightKind `json:\"kind,omitempty\"`\n}\n\n// DocumentHighlightKind a document highlight kind.\ntype DocumentHighlightKind float64\n\nconst (\n\t// DocumentHighlightKindText a textual occurrence.\n\tDocumentHighlightKindText DocumentHighlightKind = 1\n\n\t// DocumentHighlightKindRead read-access of a symbol, like reading a variable.\n\tDocumentHighlightKindRead DocumentHighlightKind = 2\n\n\t// DocumentHighlightKindWrite write-access of a symbol, like writing to a variable.\n\tDocumentHighlightKindWrite DocumentHighlightKind = 3\n)\n\n// String implements fmt.Stringer.\nfunc (k DocumentHighlightKind) String() string {\n\tswitch k {\n\tcase DocumentHighlightKindText:\n\t\treturn \"Text\"\n\tcase DocumentHighlightKindRead:\n\t\treturn \"Read\"\n\tcase DocumentHighlightKindWrite:\n\t\treturn \"Write\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// DocumentSymbolParams params of Document Symbols request.\ntype DocumentSymbolParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the text document.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n\n// SymbolKind specific capabilities for the `SymbolKind`.\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.\ntype SymbolKind float64\n\nconst (\n\t// SymbolKindFile symbol of file.\n\tSymbolKindFile SymbolKind = 1\n\t// SymbolKindModule symbol of module.\n\tSymbolKindModule SymbolKind = 2\n\t// SymbolKindNamespace symbol of namespace.\n\tSymbolKindNamespace SymbolKind = 3\n\t// SymbolKindPackage symbol of package.\n\tSymbolKindPackage SymbolKind = 4\n\t// SymbolKindClass symbol of class.\n\tSymbolKindClass SymbolKind = 5\n\t// SymbolKindMethod symbol of method.\n\tSymbolKindMethod SymbolKind = 6\n\t// SymbolKindProperty symbol of property.\n\tSymbolKindProperty SymbolKind = 7\n\t// SymbolKindField symbol of field.\n\tSymbolKindField SymbolKind = 8\n\t// SymbolKindConstructor symbol of constructor.\n\tSymbolKindConstructor SymbolKind = 9\n\t// SymbolKindEnum symbol of enum.\n\tSymbolKindEnum SymbolKind = 10\n\t// SymbolKindInterface symbol of interface.\n\tSymbolKindInterface SymbolKind = 11\n\t// SymbolKindFunction symbol of function.\n\tSymbolKindFunction SymbolKind = 12\n\t// SymbolKindVariable symbol of variable.\n\tSymbolKindVariable SymbolKind = 13\n\t// SymbolKindConstant symbol of constant.\n\tSymbolKindConstant SymbolKind = 14\n\t// SymbolKindString symbol of string.\n\tSymbolKindString SymbolKind = 15\n\t// SymbolKindNumber symbol of number.\n\tSymbolKindNumber SymbolKind = 16\n\t// SymbolKindBoolean symbol of boolean.\n\tSymbolKindBoolean SymbolKind = 17\n\t// SymbolKindArray symbol of array.\n\tSymbolKindArray SymbolKind = 18\n\t// SymbolKindObject symbol of object.\n\tSymbolKindObject SymbolKind = 19\n\t// SymbolKindKey symbol of key.\n\tSymbolKindKey SymbolKind = 20\n\t// SymbolKindNull symbol of null.\n\tSymbolKindNull SymbolKind = 21\n\t// SymbolKindEnumMember symbol of enum member.\n\tSymbolKindEnumMember SymbolKind = 22\n\t// SymbolKindStruct symbol of struct.\n\tSymbolKindStruct SymbolKind = 23\n\t// SymbolKindEvent symbol of event.\n\tSymbolKindEvent SymbolKind = 24\n\t// SymbolKindOperator symbol of operator.\n\tSymbolKindOperator SymbolKind = 25\n\t// SymbolKindTypeParameter symbol of type parameter.\n\tSymbolKindTypeParameter SymbolKind = 26\n)\n\n// String implements fmt.Stringer.\n//\n//nolint:cyclop\nfunc (k SymbolKind) String() string {\n\tswitch k {\n\tcase SymbolKindFile:\n\t\treturn \"File\"\n\tcase SymbolKindModule:\n\t\treturn \"Module\"\n\tcase SymbolKindNamespace:\n\t\treturn \"Namespace\"\n\tcase SymbolKindPackage:\n\t\treturn \"Package\"\n\tcase SymbolKindClass:\n\t\treturn \"Class\"\n\tcase SymbolKindMethod:\n\t\treturn \"Method\"\n\tcase SymbolKindProperty:\n\t\treturn \"Property\"\n\tcase SymbolKindField:\n\t\treturn \"Field\"\n\tcase SymbolKindConstructor:\n\t\treturn \"Constructor\"\n\tcase SymbolKindEnum:\n\t\treturn \"Enum\"\n\tcase SymbolKindInterface:\n\t\treturn \"Interface\"\n\tcase SymbolKindFunction:\n\t\treturn \"Function\"\n\tcase SymbolKindVariable:\n\t\treturn \"Variable\"\n\tcase SymbolKindConstant:\n\t\treturn \"Constant\"\n\tcase SymbolKindString:\n\t\treturn \"String\"\n\tcase SymbolKindNumber:\n\t\treturn \"Number\"\n\tcase SymbolKindBoolean:\n\t\treturn \"Boolean\"\n\tcase SymbolKindArray:\n\t\treturn \"Array\"\n\tcase SymbolKindObject:\n\t\treturn \"Object\"\n\tcase SymbolKindKey:\n\t\treturn \"Key\"\n\tcase SymbolKindNull:\n\t\treturn \"Null\"\n\tcase SymbolKindEnumMember:\n\t\treturn \"EnumMember\"\n\tcase SymbolKindStruct:\n\t\treturn \"Struct\"\n\tcase SymbolKindEvent:\n\t\treturn \"Event\"\n\tcase SymbolKindOperator:\n\t\treturn \"Operator\"\n\tcase SymbolKindTypeParameter:\n\t\treturn \"TypeParameter\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// SymbolTag symbol tags are extra annotations that tweak the rendering of a symbol.\n//\n// @since 3.16.0.\ntype SymbolTag float64\n\n// list of SymbolTag.\nconst (\n\t// SymbolTagDeprecated render a symbol as obsolete, usually using a strike-out.\n\tSymbolTagDeprecated SymbolTag = 1\n)\n\n// String returns a string representation of the SymbolTag.\nfunc (k SymbolTag) String() string {\n\tswitch k {\n\tcase SymbolTagDeprecated:\n\t\treturn \"Deprecated\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// DocumentSymbol represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be\n// hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,\n// e.g. the range of an identifier.\ntype DocumentSymbol struct {\n\t// Name is the name of this symbol. Will be displayed in the user interface and therefore must not be\n\t// an empty string or a string only consisting of white spaces.\n\tName string `json:\"name\"`\n\n\t// Detail is the more detail for this symbol, e.g the signature of a function.\n\tDetail string `json:\"detail,omitempty\"`\n\n\t// Kind is the kind of this symbol.\n\tKind SymbolKind `json:\"kind\"`\n\n\t// Tags for this document symbol.\n\t//\n\t// @since 3.16.0.\n\tTags []SymbolTag `json:\"tags,omitempty\"`\n\n\t// Deprecated indicates if this symbol is deprecated.\n\tDeprecated bool `json:\"deprecated,omitempty\"`\n\n\t// Range is the range enclosing this symbol not including leading/trailing whitespace but everything else\n\t// like comments. This information is typically used to determine if the clients cursor is\n\t// inside the symbol to reveal in the symbol in the UI.\n\tRange Range `json:\"range\"`\n\n\t// SelectionRange is the range that should be selected and revealed when this symbol is being picked, e.g the name of a function.\n\t// Must be contained by the `range`.\n\tSelectionRange Range `json:\"selectionRange\"`\n\n\t// Children children of this symbol, e.g. properties of a class.\n\tChildren []DocumentSymbol `json:\"children,omitempty\"`\n}\n\n// SymbolInformation represents information about programming constructs like variables, classes,\n// interfaces etc.\ntype SymbolInformation struct {\n\t// Name is the name of this symbol.\n\tName string `json:\"name\"`\n\n\t// Kind is the kind of this symbol.\n\tKind SymbolKind `json:\"kind\"`\n\n\t// Tags for this completion item.\n\t//\n\t// @since 3.16.0.\n\tTags []SymbolTag `json:\"tags,omitempty\"`\n\n\t// Deprecated indicates if this symbol is deprecated.\n\tDeprecated bool `json:\"deprecated,omitempty\"`\n\n\t// Location is the location of this symbol. The location's range is used by a tool\n\t// to reveal the location in the editor. If the symbol is selected in the\n\t// tool the range's start information is used to position the cursor. So\n\t// the range usually spans more then the actual symbol's name and does\n\t// normally include things like visibility modifiers.\n\t//\n\t// The range doesn't have to denote a node range in the sense of a abstract\n\t// syntax tree. It can therefore not be used to re-construct a hierarchy of\n\t// the symbols.\n\tLocation Location `json:\"location\"`\n\n\t// ContainerName is the name of the symbol containing this symbol. This information is for\n\t// user interface purposes (e.g. to render a qualifier in the user interface\n\t// if necessary). It can't be used to re-infer a hierarchy for the document\n\t// symbols.\n\tContainerName string `json:\"containerName,omitempty\"`\n}\n\ntype SymbolInformationOrDocumentSymbol struct {\n\tSymbolInformation *SymbolInformation\n\tDocumentSymbol    *DocumentSymbol\n}\n\nfunc (s *SymbolInformationOrDocumentSymbol) MarshalJSON() ([]byte, error) {\n\tif s.SymbolInformation != nil {\n\t\treturn json.Marshal(s.SymbolInformation)\n\t}\n\treturn json.Marshal(s.DocumentSymbol)\n}\n\nfunc (s *SymbolInformationOrDocumentSymbol) UnmarshalJSON(data []byte) error {\n\tvar si SymbolInformation\n\tif err := json.Unmarshal(data, &si); err != nil {\n\t\treturn err\n\t}\n\ts.SymbolInformation = &si\n\n\tvar ds DocumentSymbol\n\terr := json.Unmarshal(data, &ds)\n\tif err != nil {\n\t\treturn err\n\t}\n\ts.DocumentSymbol = &ds\n\n\t// Only SymbolInformation has a location URI.\n\tif s.SymbolInformation.Location.URI == \"\" {\n\t\ts.SymbolInformation = nil\n\t} else {\n\t\ts.DocumentSymbol = nil\n\t}\n\n\treturn nil\n}\n\n// CodeActionParams params for the CodeActionRequest.\ntype CodeActionParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the document in which the command was invoked.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Context carrying additional information.\n\tContext CodeActionContext `json:\"context\"`\n\n\t// Range is the range for which the command was invoked.\n\tRange Range `json:\"range\"`\n}\n\n// CodeActionKind is 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.\ntype CodeActionKind string\n\n// A set of predefined code action kinds.\nconst (\n\t// QuickFix base kind for quickfix actions: 'quickfix'.\n\tQuickFix CodeActionKind = \"quickfix\"\n\n\t// Refactor base kind for refactoring actions: 'refactor'.\n\tRefactor CodeActionKind = \"refactor\"\n\n\t// RefactorExtract base kind for refactoring extraction actions: 'refactor.extract'\n\t//\n\t// Example extract actions:\n\t//\n\t// - Extract method\n\t// - Extract function\n\t// - Extract variable\n\t// - Extract interface from class\n\t// - ...\n\tRefactorExtract CodeActionKind = \"refactor.extract\"\n\n\t// RefactorInline base kind for refactoring inline actions: 'refactor.inline'\n\t//\n\t// Example inline actions:\n\t//\n\t// - Inline function\n\t// - Inline variable\n\t// - Inline constant\n\t// - ...\n\tRefactorInline CodeActionKind = \"refactor.inline\"\n\n\t// RefactorRewrite base kind for refactoring rewrite actions: 'refactor.rewrite'\n\t//\n\t// Example rewrite actions:\n\t//\n\t// - Convert JavaScript function to class\n\t// - Add or remove parameter\n\t// - Encapsulate field\n\t// - Make method static\n\t// - Move method to base class\n\t// - ...\n\tRefactorRewrite CodeActionKind = \"refactor.rewrite\"\n\n\t// Source base kind for source actions: `source`\n\t//\n\t// Source code actions apply to the entire file.\n\tSource CodeActionKind = \"source\"\n\n\t// SourceOrganizeImports base kind for an organize imports source action: `source.organizeImports`.\n\tSourceOrganizeImports CodeActionKind = \"source.organizeImports\"\n)\n\n// CodeActionContext contains additional diagnostic information about the context in which\n// a code action is run.\ntype CodeActionContext struct {\n\t// Diagnostics is an array of diagnostics.\n\tDiagnostics []Diagnostic `json:\"diagnostics\"`\n\n\t// Only requested kind of actions to return.\n\t//\n\t// Actions not of this kind are filtered out by the client before being shown. So servers\n\t// can omit computing them.\n\tOnly []CodeActionKind `json:\"only,omitempty\"`\n}\n\n// CodeAction capabilities specific to the `textDocument/codeAction`.\ntype CodeAction struct {\n\t// Title is a short, human-readable, title for this code action.\n\tTitle string `json:\"title\"`\n\n\t// Kind is the kind of the code action.\n\t//\n\t// Used to filter code actions.\n\tKind CodeActionKind `json:\"kind,omitempty\"`\n\n\t// Diagnostics is the diagnostics that this code action resolves.\n\tDiagnostics []Diagnostic `json:\"diagnostics,omitempty\"`\n\n\t// IsPreferred marks this as a preferred action. Preferred actions are used by the `auto fix` command and can be targeted\n\t// by keybindings.\n\t//\n\t// A quick fix should be marked preferred if it properly addresses the underlying error.\n\t// A refactoring should be marked preferred if it is the most reasonable choice of actions to take.\n\t//\n\t// @since 3.15.0.\n\tIsPreferred bool `json:\"isPreferred,omitempty\"`\n\n\t// Disabled marks that the code action cannot currently be applied.\n\t//\n\t// Clients should follow the following guidelines regarding disabled code\n\t// actions:\n\t//\n\t//  - Disabled code actions are not shown in automatic lightbulbs code\n\t//    action menus.\n\t//\n\t//  - Disabled actions are shown as faded out in the code action menu when\n\t//    the user request a more specific type of code action, such as\n\t//    refactorings.\n\t//\n\t//  - If the user has a keybinding that auto applies a code action and only\n\t//    a disabled code actions are returned, the client should show the user\n\t//    an error message with `reason` in the editor.\n\t//\n\t// @since 3.16.0.\n\tDisabled *CodeActionDisable `json:\"disabled,omitempty\"`\n\n\t// Edit is the workspace edit this code action performs.\n\tEdit *WorkspaceEdit `json:\"edit,omitempty\"`\n\n\t// Command is a command this code action executes. If a code action\n\t// provides an edit and a command, first the edit is\n\t// executed and then the command.\n\tCommand *Command `json:\"command,omitempty\"`\n\n\t// Data is a data entry field that is preserved on a code action between\n\t// a \"textDocument/codeAction\" and a \"codeAction/resolve\" request.\n\t//\n\t// @since 3.16.0.\n\tData any `json:\"data,omitempty\"`\n}\n\n// CodeActionDisable Disable in CodeAction.\n//\n// @since 3.16.0.\ntype CodeActionDisable struct {\n\t// Reason human readable description of why the code action is currently\n\t// disabled.\n\t//\n\t// This is displayed in the code actions UI.\n\tReason string `json:\"reason\"`\n}\n\n// CodeActionRegistrationOptions CodeAction Registrationi options.\ntype CodeActionRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\tCodeActionOptions\n}\n\n// CodeLensParams params of Code Lens request.\ntype CodeLensParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the document to request code lens for.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n\n// CodeLens is 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.\ntype CodeLens struct {\n\t// Range is the range in which this code lens is valid. Should only span a single line.\n\tRange Range `json:\"range\"`\n\n\t// Command is the command this code lens represents.\n\tCommand *Command `json:\"command,omitempty\"`\n\n\t// Data is a data entry field that is preserved on a code lens item between\n\t// a code lens and a code lens resolve request.\n\tData any `json:\"data,omitempty\"`\n}\n\n// CodeLensRegistrationOptions CodeLens Registration options.\ntype CodeLensRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// ResolveProvider code lens has a resolve provider as well.\n\tResolveProvider bool `json:\"resolveProvider,omitempty\"`\n}\n\n// DocumentLinkParams params of Document Link request.\ntype DocumentLinkParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the document to provide document links for.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n\n// DocumentLink is 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.\ntype DocumentLink struct {\n\t// Range is the range this link applies to.\n\tRange Range `json:\"range\"`\n\n\t// Target is the uri this link points to. If missing a resolve request is sent later.\n\tTarget DocumentURI `json:\"target,omitempty\"`\n\n\t// Tooltip is the tooltip text when you hover over this link.\n\t//\n\t// If a tooltip is provided, is will be displayed in a string that includes instructions on how to\n\t// trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS,\n\t// user settings, and localization.\n\t//\n\t// @since 3.15.0.\n\tTooltip string `json:\"tooltip,omitempty\"`\n\n\t// Data is a data entry field that is preserved on a document link between a\n\t// DocumentLinkRequest and a DocumentLinkResolveRequest.\n\tData any `json:\"data,omitempty\"`\n}\n\n// DocumentColorParams params of Document Color request.\ntype DocumentColorParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the document to format.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n\n// ColorInformation response of Document Color request.\ntype ColorInformation struct {\n\t// Range is the range in the document where this color appears.\n\tRange Range `json:\"range\"`\n\n\t// Color is the actual color value for this color range.\n\tColor Color `json:\"color\"`\n}\n\n// Color represents a color in RGBA space.\ntype Color struct {\n\t// Alpha is the alpha component of this color in the range [0-1].\n\tAlpha float64 `json:\"alpha\"`\n\n\t// Blue is the blue component of this color in the range [0-1].\n\tBlue float64 `json:\"blue\"`\n\n\t// Green is the green component of this color in the range [0-1].\n\tGreen float64 `json:\"green\"`\n\n\t// Red is the red component of this color in the range [0-1].\n\tRed float64 `json:\"red\"`\n}\n\n// ColorPresentationParams params of Color Presentation request.\ntype ColorPresentationParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the text document.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Color is the color information to request presentations for.\n\tColor Color `json:\"color\"`\n\n\t// Range is the range where the color would be inserted. Serves as a context.\n\tRange Range `json:\"range\"`\n}\n\n// ColorPresentation response of Color Presentation request.\ntype ColorPresentation struct {\n\t// Label is the label of this color presentation. It will be shown on the color\n\t// picker header. By default this is also the text that is inserted when selecting\n\t// this color presentation.\n\tLabel string `json:\"label\"`\n\n\t// TextEdit an edit which is applied to a document when selecting\n\t// this presentation for the color.  When `falsy` the label is used.\n\tTextEdit *TextEdit `json:\"textEdit,omitempty\"`\n\n\t// AdditionalTextEdits an optional array of additional [text edits](#TextEdit) that are applied when\n\t// selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves.\n\tAdditionalTextEdits []TextEdit `json:\"additionalTextEdits,omitempty\"`\n}\n\n// DocumentFormattingParams params of Document Formatting request.\ntype DocumentFormattingParams struct {\n\tWorkDoneProgressParams\n\n\t// Options is the format options.\n\tOptions FormattingOptions `json:\"options\"`\n\n\t// TextDocument is the document to format.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n\n// FormattingOptions value-object describing what options formatting should use.\ntype FormattingOptions struct {\n\t// InsertSpaces prefer spaces over tabs.\n\tInsertSpaces bool `json:\"insertSpaces\"`\n\n\t// TabSize size of a tab in spaces.\n\tTabSize uint32 `json:\"tabSize\"`\n\n\t// TrimTrailingWhitespace trim trailing whitespaces on a line.\n\t//\n\t// @since 3.15.0.\n\tTrimTrailingWhitespace bool `json:\"trimTrailingWhitespace,omitempty\"`\n\n\t// InsertFinalNewlines insert a newline character at the end of the file if one does not exist.\n\t//\n\t// @since 3.15.0.\n\tInsertFinalNewline bool `json:\"insertFinalNewline,omitempty\"`\n\n\t// TrimFinalNewlines trim all newlines after the final newline at the end of the file.\n\t//\n\t// @since 3.15.0.\n\tTrimFinalNewlines bool `json:\"trimFinalNewlines,omitempty\"`\n\n\t// Key is the signature for further properties.\n\tKey map[string]any `json:\"key,omitempty\"` // bool | int32 | string\n}\n\n// DocumentRangeFormattingParams params of Document Range Formatting request.\ntype DocumentRangeFormattingParams struct {\n\tWorkDoneProgressParams\n\n\t// TextDocument is the document to format.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Range is the range to format\n\tRange Range `json:\"range\"`\n\n\t// Options is the format options.\n\tOptions FormattingOptions `json:\"options\"`\n}\n\n// DocumentOnTypeFormattingParams params of Document on Type Formatting request.\ntype DocumentOnTypeFormattingParams struct {\n\t// TextDocument is the document to format.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Position is the position at which this request was sent.\n\tPosition Position `json:\"position\"`\n\n\t// Ch is the character that has been typed.\n\tCh string `json:\"ch\"`\n\n\t// Options is the format options.\n\tOptions FormattingOptions `json:\"options\"`\n}\n\n// DocumentOnTypeFormattingRegistrationOptions DocumentOnTypeFormatting Registration options.\ntype DocumentOnTypeFormattingRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// FirstTriggerCharacter a character on which formatting should be triggered, like `}`.\n\tFirstTriggerCharacter string `json:\"firstTriggerCharacter\"`\n\n\t// MoreTriggerCharacter a More trigger characters.\n\tMoreTriggerCharacter []string `json:\"moreTriggerCharacter\"`\n}\n\n// RenameParams params of Rename request.\ntype RenameParams struct {\n\tTextDocumentPositionParams\n\tPartialResultParams\n\n\t// NewName is the new name of the symbol. If the given name is not valid the\n\t// request must return a [ResponseError](#ResponseError) with an\n\t// appropriate message set.\n\tNewName string `json:\"newName\"`\n}\n\n// RenameRegistrationOptions Rename Registration options.\ntype RenameRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// PrepareProvider is the renames should be checked and tested for validity before being executed.\n\tPrepareProvider bool `json:\"prepareProvider,omitempty\"`\n}\n\n// PrepareRenameParams params of PrepareRenameParams request.\n//\n// @since 3.15.0.\ntype PrepareRenameParams struct {\n\tTextDocumentPositionParams\n}\n\n// FoldingRangeParams params of Folding Range request.\ntype FoldingRangeParams struct {\n\tTextDocumentPositionParams\n\tPartialResultParams\n}\n\n// FoldingRangeKind is the enum of known range kinds.\ntype FoldingRangeKind string\n\nconst (\n\t// CommentFoldingRange is the folding range for a comment.\n\tCommentFoldingRange FoldingRangeKind = \"comment\"\n\n\t// ImportsFoldingRange is the folding range for a imports or includes.\n\tImportsFoldingRange FoldingRangeKind = \"imports\"\n\n\t// RegionFoldingRange is the folding range for a region (e.g. `#region`).\n\tRegionFoldingRange FoldingRangeKind = \"region\"\n)\n\n// FoldingRange capabilities specific to `textDocument/foldingRange` requests.\n//\n// @since 3.10.0.\ntype FoldingRange struct {\n\t// StartLine is the zero-based line number from where the folded range starts.\n\tStartLine uint32 `json:\"startLine\"`\n\n\t// StartCharacter is the zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.\n\tStartCharacter uint32 `json:\"startCharacter,omitempty\"`\n\n\t// EndLine is the zero-based line number where the folded range ends.\n\tEndLine uint32 `json:\"endLine\"`\n\n\t// EndCharacter is the zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.\n\tEndCharacter uint32 `json:\"endCharacter,omitempty\"`\n\n\t// Kind describes the kind of the folding range such as `comment' or 'region'. The kind\n\t// is used to categorize folding ranges and used by commands like 'Fold all comments'.\n\t// See FoldingRangeKind for an enumeration of standardized kinds.\n\tKind FoldingRangeKind `json:\"kind,omitempty\"`\n}\n"
  },
  {
    "path": "lsp/protocol/language_test.go",
    "content": "// SPDX-FileCopyrightText: 2020 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\nfunc TestCompletionParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"context\":{\"triggerCharacter\":\".\",\"triggerKind\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":2,\"character\":0},\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"context\":{\"triggerCharacter\":\".\",\"triggerKind\":1}}`\n\t)\n\twantType := CompletionParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tContext: &CompletionContext{\n\t\t\tTriggerCharacter: \".\",\n\t\t\tTriggerKind:      CompletionTriggerKindInvoked,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CompletionParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CompletionParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CompletionParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCompletionTriggerKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    CompletionTriggerKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Invoked\",\n\t\t\tk:    CompletionTriggerKindInvoked,\n\t\t\twant: \"Invoked\",\n\t\t},\n\t\t{\n\t\t\tname: \"TriggerCharacter\",\n\t\t\tk:    CompletionTriggerKindTriggerCharacter,\n\t\t\twant: \"TriggerCharacter\",\n\t\t},\n\t\t{\n\t\t\tname: \"TriggerForIncompleteCompletions\",\n\t\t\tk:    CompletionTriggerKindTriggerForIncompleteCompletions,\n\t\t\twant: \"TriggerForIncompleteCompletions\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    CompletionTriggerKind(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"CompletionTriggerKind.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCompletionContext(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"triggerCharacter\":\".\",\"triggerKind\":1}`\n\t\twantInvalid = `{\"triggerCharacter\":\" \",\"triggerKind\":0}`\n\t)\n\twantType := CompletionContext{\n\t\tTriggerCharacter: \".\",\n\t\tTriggerKind:      CompletionTriggerKindInvoked,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CompletionContext\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CompletionContext\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CompletionContext\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCompletionList(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"isIncomplete\":true,\"items\":[{\"tags\":[1],\"detail\":\"string\",\"documentation\":\"Detail a human-readable string with additional information about this item, like type or symbol information.\",\"filterText\":\"Detail\",\"insertTextFormat\":2,\"kind\":5,\"label\":\"Detail\",\"preselect\":true,\"sortText\":\"00000\",\"textEdit\":{\"range\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}},\"newText\":\"Detail: ${1:},\"}}]}`\n\t\twantInvalid = `{\"isIncomplete\":false,\"items\":[]}`\n\t)\n\twantType := CompletionList{\n\t\tIsIncomplete: true,\n\t\tItems: []CompletionItem{\n\t\t\t{\n\t\t\t\tAdditionalTextEdits: nil,\n\t\t\t\tCommand:             nil,\n\t\t\t\tCommitCharacters:    nil,\n\t\t\t\tTags: []CompletionItemTag{\n\t\t\t\t\tCompletionItemTagDeprecated,\n\t\t\t\t},\n\t\t\t\tDeprecated:       false,\n\t\t\t\tDetail:           \"string\",\n\t\t\t\tDocumentation:    \"Detail a human-readable string with additional information about this item, like type or symbol information.\",\n\t\t\t\tFilterText:       \"Detail\",\n\t\t\t\tInsertText:       \"\",\n\t\t\t\tInsertTextFormat: InsertTextFormatSnippet,\n\t\t\t\tKind:             CompletionItemKindField,\n\t\t\t\tLabel:            \"Detail\",\n\t\t\t\tPreselect:        true,\n\t\t\t\tSortText:         \"00000\",\n\t\t\t\tTextEdit: &TextEditOrInsertReplaceEdit{\n\t\t\t\t\tTextEdit: &TextEdit{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\t\t\tCharacter: 10,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tNewText: \"Detail: ${1:},\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CompletionList\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CompletionList\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CompletionList\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestInsertTextFormat_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    InsertTextFormat\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"PlainText\",\n\t\t\tk:    InsertTextFormatPlainText,\n\t\t\twant: \"PlainText\",\n\t\t},\n\t\t{\n\t\t\tname: \"Snippet\",\n\t\t\tk:    InsertTextFormatSnippet,\n\t\t\twant: \"Snippet\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    InsertTextFormat(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"InsertTextFormat.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestInsertReplaceEdit(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant = `{\"newText\":\"testNewText\",\"insert\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}},\"replace\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}}}`\n\t)\n\twantType := InsertReplaceEdit{\n\t\tNewText: \"testNewText\",\n\t\tInsert: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 4,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 10,\n\t\t\t},\n\t\t},\n\t\tReplace: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 4,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 10,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          InsertReplaceEdit\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             InsertReplaceEdit\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got InsertReplaceEdit\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestInsertTextMode_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    InsertTextMode\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"AsIs\",\n\t\t\tk:    InsertTextModeAsIs,\n\t\t\twant: \"AsIs\",\n\t\t},\n\t\t{\n\t\t\tname: \"AdjustIndentation\",\n\t\t\tk:    InsertTextModeAdjustIndentation,\n\t\t\twant: \"AdjustIndentation\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    InsertTextMode(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"InsertTextMode.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCompletionItem(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantTextEdit = `{\n  \"additionalTextEdits\": [\n    {\n      \"range\": {\n        \"start\": {\n          \"line\": 255,\n          \"character\": 4\n        },\n        \"end\": {\n          \"line\": 255,\n          \"character\": 10\n        }\n      },\n      \"newText\": \"Detail: ${1:},\"\n    }\n  ],\n  \"command\": {\n    \"title\": \"exec echo\",\n    \"command\": \"echo\",\n    \"arguments\": [\n      \"hello\"\n    ]\n  },\n  \"commitCharacters\": [\n    \"a\"\n  ],\n  \"tags\": [\n    1\n  ],\n  \"data\": \"testData\",\n  \"deprecated\": true,\n  \"detail\": \"string\",\n  \"documentation\": \"Detail a human-readable string with additional information about this item, like type or symbol information.\",\n  \"filterText\": \"Detail\",\n  \"insertText\": \"testInsert\",\n  \"insertTextFormat\": 2,\n  \"insertTextMode\": 1,\n  \"kind\": 5,\n  \"label\": \"Detail\",\n  \"preselect\": true,\n  \"sortText\": \"00000\",\n  \"textEdit\": {\n    \"range\": {\n      \"start\": {\n        \"line\": 255,\n        \"character\": 4\n      },\n      \"end\": {\n        \"line\": 255,\n        \"character\": 10\n      }\n    },\n    \"newText\": \"Detail: ${1:},\"\n  }\n}`\n\t\twantInsertReplaceEdit = `{\n  \"additionalTextEdits\": [\n    {\n      \"range\": {\n        \"start\": {\n          \"line\": 255,\n          \"character\": 4\n        },\n        \"end\": {\n          \"line\": 255,\n          \"character\": 10\n        }\n      },\n      \"newText\": \"Detail: ${1:},\"\n    }\n  ],\n  \"command\": {\n    \"title\": \"exec echo\",\n    \"command\": \"echo\",\n    \"arguments\": [\n      \"hello\"\n    ]\n  },\n  \"commitCharacters\": [\n    \"a\"\n  ],\n  \"tags\": [\n    1\n  ],\n  \"data\": \"testData\",\n  \"deprecated\": true,\n  \"detail\": \"string\",\n  \"documentation\": \"Detail a human-readable string with additional information about this item, like type or symbol information.\",\n  \"filterText\": \"Detail\",\n  \"insertText\": \"testInsert\",\n  \"insertTextFormat\": 2,\n  \"insertTextMode\": 1,\n  \"kind\": 5,\n  \"label\": \"Detail\",\n  \"preselect\": true,\n  \"sortText\": \"00000\",\n  \"textEdit\": {\n    \"newText\": \"Detail: ${1:},\",\n    \"insert\": {\n      \"start\": {\n        \"line\": 105,\n        \"character\": 65\n      },\n      \"end\": {\n        \"line\": 105,\n        \"character\": 72\n      }\n    },\n    \"replace\": {\n      \"start\": {\n        \"line\": 105,\n        \"character\": 65\n      },\n      \"end\": {\n        \"line\": 105,\n        \"character\": 76\n      }\n    }\n  }\n}`\n\t\twantNilAll = `{\n  \"label\": \"Detail\"\n}`\n\t\twantInvalid = `{\"items\":[]}`\n\t)\n\twantTypeTextEdit := CompletionItem{\n\t\tAdditionalTextEdits: []TextEdit{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNewText: \"Detail: ${1:},\",\n\t\t\t},\n\t\t},\n\t\tCommand: &Command{\n\t\t\tTitle:     \"exec echo\",\n\t\t\tCommand:   \"echo\",\n\t\t\tArguments: []any{\"hello\"},\n\t\t},\n\t\tCommitCharacters: []string{\"a\"},\n\t\tTags: []CompletionItemTag{\n\t\t\tCompletionItemTagDeprecated,\n\t\t},\n\t\tData:             \"testData\",\n\t\tDeprecated:       true,\n\t\tDetail:           \"string\",\n\t\tDocumentation:    \"Detail a human-readable string with additional information about this item, like type or symbol information.\",\n\t\tFilterText:       \"Detail\",\n\t\tInsertText:       \"testInsert\",\n\t\tInsertTextFormat: InsertTextFormatSnippet,\n\t\tInsertTextMode:   InsertTextModeAsIs,\n\t\tKind:             CompletionItemKindField,\n\t\tLabel:            \"Detail\",\n\t\tPreselect:        true,\n\t\tSortText:         \"00000\",\n\t\tTextEdit: &TextEditOrInsertReplaceEdit{\n\t\t\tTextEdit: &TextEdit{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNewText: \"Detail: ${1:},\",\n\t\t\t},\n\t\t},\n\t}\n\twantTypeInsertReplaceEdit := CompletionItem{\n\t\tAdditionalTextEdits: []TextEdit{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNewText: \"Detail: ${1:},\",\n\t\t\t},\n\t\t},\n\t\tCommand: &Command{\n\t\t\tTitle:     \"exec echo\",\n\t\t\tCommand:   \"echo\",\n\t\t\tArguments: []any{\"hello\"},\n\t\t},\n\t\tCommitCharacters: []string{\"a\"},\n\t\tTags: []CompletionItemTag{\n\t\t\tCompletionItemTagDeprecated,\n\t\t},\n\t\tData:             \"testData\",\n\t\tDeprecated:       true,\n\t\tDetail:           \"string\",\n\t\tDocumentation:    \"Detail a human-readable string with additional information about this item, like type or symbol information.\",\n\t\tFilterText:       \"Detail\",\n\t\tInsertText:       \"testInsert\",\n\t\tInsertTextFormat: InsertTextFormatSnippet,\n\t\tInsertTextMode:   InsertTextModeAsIs,\n\t\tKind:             CompletionItemKindField,\n\t\tLabel:            \"Detail\",\n\t\tPreselect:        true,\n\t\tSortText:         \"00000\",\n\t\tTextEdit: &TextEditOrInsertReplaceEdit{\n\t\t\tInsertReplaceEdit: &InsertReplaceEdit{\n\t\t\t\tNewText: \"Detail: ${1:},\",\n\t\t\t\tInsert: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      105,\n\t\t\t\t\t\tCharacter: 65,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      105,\n\t\t\t\t\t\tCharacter: 72,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tReplace: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      105,\n\t\t\t\t\t\tCharacter: 65,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      105,\n\t\t\t\t\t\tCharacter: 76,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := CompletionItem{\n\t\tLabel: \"Detail\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CompletionItem\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"ValidTextEdit\",\n\t\t\t\tfield:          wantTypeTextEdit,\n\t\t\t\twant:           wantTextEdit,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidInsertReplaceEdit\",\n\t\t\t\tfield:          wantTypeInsertReplaceEdit,\n\t\t\t\twant:           wantInsertReplaceEdit,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantTypeTextEdit,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tb := new(bytes.Buffer)\n\t\t\t\tenc := json.NewEncoder(b)\n\t\t\t\tenc.SetIndent(\"\", \"  \")\n\t\t\t\terr := enc.Encode(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\t\t\t\tgot := strings.TrimSpace(b.String())\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CompletionItem\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"ValidTextEdit\",\n\t\t\t\tfield:            wantTextEdit,\n\t\t\t\twant:             wantTypeTextEdit,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidInsertReplaceEdit\",\n\t\t\t\tfield:            wantInsertReplaceEdit,\n\t\t\t\twant:             wantTypeInsertReplaceEdit,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantTypeTextEdit,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CompletionItem\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCompletionItemKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    CompletionItemKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Text\",\n\t\t\tk:    CompletionItemKindText,\n\t\t\twant: \"Text\",\n\t\t},\n\t\t{\n\t\t\tname: \"Method\",\n\t\t\tk:    CompletionItemKindMethod,\n\t\t\twant: \"Method\",\n\t\t},\n\t\t{\n\t\t\tname: \"Function\",\n\t\t\tk:    CompletionItemKindFunction,\n\t\t\twant: \"Function\",\n\t\t},\n\t\t{\n\t\t\tname: \"Constructor\",\n\t\t\tk:    CompletionItemKindConstructor,\n\t\t\twant: \"Constructor\",\n\t\t},\n\t\t{\n\t\t\tname: \"Field\",\n\t\t\tk:    CompletionItemKindField,\n\t\t\twant: \"Field\",\n\t\t},\n\t\t{\n\t\t\tname: \"Variable\",\n\t\t\tk:    CompletionItemKindVariable,\n\t\t\twant: \"Variable\",\n\t\t},\n\t\t{\n\t\t\tname: \"Class\",\n\t\t\tk:    CompletionItemKindClass,\n\t\t\twant: \"Class\",\n\t\t},\n\t\t{\n\t\t\tname: \"Interface\",\n\t\t\tk:    CompletionItemKindInterface,\n\t\t\twant: \"Interface\",\n\t\t},\n\t\t{\n\t\t\tname: \"Module\",\n\t\t\tk:    CompletionItemKindModule,\n\t\t\twant: \"Module\",\n\t\t},\n\t\t{\n\t\t\tname: \"Property\",\n\t\t\tk:    CompletionItemKindProperty,\n\t\t\twant: \"Property\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unit\",\n\t\t\tk:    CompletionItemKindUnit,\n\t\t\twant: \"Unit\",\n\t\t},\n\t\t{\n\t\t\tname: \"Value\",\n\t\t\tk:    CompletionItemKindValue,\n\t\t\twant: \"Value\",\n\t\t},\n\t\t{\n\t\t\tname: \"Enum\",\n\t\t\tk:    CompletionItemKindEnum,\n\t\t\twant: \"Enum\",\n\t\t},\n\t\t{\n\t\t\tname: \"Keyword\",\n\t\t\tk:    CompletionItemKindKeyword,\n\t\t\twant: \"Keyword\",\n\t\t},\n\t\t{\n\t\t\tname: \"Snippet\",\n\t\t\tk:    CompletionItemKindSnippet,\n\t\t\twant: \"Snippet\",\n\t\t},\n\t\t{\n\t\t\tname: \"Color\",\n\t\t\tk:    CompletionItemKindColor,\n\t\t\twant: \"Color\",\n\t\t},\n\t\t{\n\t\t\tname: \"File\",\n\t\t\tk:    CompletionItemKindFile,\n\t\t\twant: \"File\",\n\t\t},\n\t\t{\n\t\t\tname: \"Reference\",\n\t\t\tk:    CompletionItemKindReference,\n\t\t\twant: \"Reference\",\n\t\t},\n\t\t{\n\t\t\tname: \"Folder\",\n\t\t\tk:    CompletionItemKindFolder,\n\t\t\twant: \"Folder\",\n\t\t},\n\t\t{\n\t\t\tname: \"EnumMember\",\n\t\t\tk:    CompletionItemKindEnumMember,\n\t\t\twant: \"EnumMember\",\n\t\t},\n\t\t{\n\t\t\tname: \"Constant\",\n\t\t\tk:    CompletionItemKindConstant,\n\t\t\twant: \"Constant\",\n\t\t},\n\t\t{\n\t\t\tname: \"Struct\",\n\t\t\tk:    CompletionItemKindStruct,\n\t\t\twant: \"Struct\",\n\t\t},\n\t\t{\n\t\t\tname: \"Event\",\n\t\t\tk:    CompletionItemKindEvent,\n\t\t\twant: \"Event\",\n\t\t},\n\t\t{\n\t\t\tname: \"Operator\",\n\t\t\tk:    CompletionItemKindOperator,\n\t\t\twant: \"Operator\",\n\t\t},\n\t\t{\n\t\t\tname: \"TypeParameter\",\n\t\t\tk:    CompletionItemKindTypeParameter,\n\t\t\twant: \"TypeParameter\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    CompletionItemKind(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"CompletionItemKind.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCompletionItemTag_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    CompletionItemTag\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Deprecated\",\n\t\t\tk:    CompletionItemTagDeprecated,\n\t\t\twant: \"Deprecated\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    CompletionItemTag(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"CompletionItemTag.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCompletionRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"}],\"triggerCharacters\":[\".\"],\"resolveProvider\":true}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"triggerCharacters\":[\" \"],\"resolveProvider\":true}`\n\t)\n\twantType := CompletionRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tTriggerCharacters: []string{\".\"},\n\t\tResolveProvider:   true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CompletionRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CompletionRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CompletionRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestHoverParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidWorkDoneToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\"}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + invalidWorkDoneToken + `\"}`\n\t)\n\twantType := HoverParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t}\n\twantTypeNilAll := HoverParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          HoverParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             HoverParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got HoverParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestHover(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"contents\":{\"kind\":\"markdown\",\"value\":\"example value\"},\"range\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}}}`\n\t\twantInvalid = `{\"contents\":{\"kind\":\"markdown\",\"value\":\"example value\"},\"range\":{\"start\":{\"line\":25,\"character\":2},\"end\":{\"line\":25,\"character\":5}}}`\n\t)\n\twantType := Hover{\n\t\tContents: MarkupContent{\n\t\t\tKind:  Markdown,\n\t\t\tValue: \"example value\",\n\t\t},\n\t\tRange: &Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 4,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 10,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Hover\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Hover\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Hover\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSignatureHelpParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidWorkDoneToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1},\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"context\":{\"triggerKind\":1,\"triggerCharacter\":\".\",\"isRetrigger\":true,\"activeSignatureHelp\":{\"signatures\":[{\"label\":\"testLabel\",\"documentation\":\"testDocumentation\",\"parameters\":[{\"label\":\"test label\",\"documentation\":\"test documentation\"}]}],\"activeParameter\":10,\"activeSignature\":5}}}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\"},\"position\":{\"line\":2,\"character\":1},\"workDoneToken\":\"` + invalidWorkDoneToken + `\",\"context\":{\"triggerKind\":0,\"triggerCharacter\":\"aaa\",\"isRetrigger\":false,\"activeSignatureHelp\":{\"signatures\":[{\"documentationFormat\":[\"markdown\"],\"parameterInformation\":{\"label\":\"test label\",\"documentation\":\"test documentation\"}}],\"activeParameter\":1,\"activeSignature\":0}}}`\n\t)\n\twantType := SignatureHelpParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tContext: &SignatureHelpContext{\n\t\t\tTriggerKind:      SignatureHelpTriggerKindInvoked,\n\t\t\tTriggerCharacter: \".\",\n\t\t\tIsRetrigger:      true,\n\t\t\tActiveSignatureHelp: &SignatureHelp{\n\t\t\t\tSignatures: []SignatureInformation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLabel:         \"testLabel\",\n\t\t\t\t\t\tDocumentation: \"testDocumentation\",\n\t\t\t\t\t\tParameters: []ParameterInformation{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tLabel:         \"test label\",\n\t\t\t\t\t\t\t\tDocumentation: \"test documentation\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tActiveParameter: 10,\n\t\t\t\tActiveSignature: 5,\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := SignatureHelpParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SignatureHelpParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SignatureHelpParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SignatureHelpParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSignatureHelpTriggerKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    SignatureHelpTriggerKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Invoked\",\n\t\t\tk:    SignatureHelpTriggerKindInvoked,\n\t\t\twant: \"Invoked\",\n\t\t},\n\t\t{\n\t\t\tname: \"TriggerCharacter\",\n\t\t\tk:    SignatureHelpTriggerKindTriggerCharacter,\n\t\t\twant: \"TriggerCharacter\",\n\t\t},\n\t\t{\n\t\t\tname: \"ContentChange\",\n\t\t\tk:    SignatureHelpTriggerKindContentChange,\n\t\t\twant: \"ContentChange\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    SignatureHelpTriggerKind(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"SignatureHelpTriggerKind.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSignatureHelp(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"signatures\":[{\"label\":\"testLabel\",\"documentation\":\"testDocumentation\",\"parameters\":[{\"label\":\"test label\",\"documentation\":\"test documentation\"}]}],\"activeParameter\":10,\"activeSignature\":5}`\n\t\twantNilAll  = `{\"signatures\":[]}`\n\t\twantInvalid = `{\"signatures\":[{\"label\":\"invalidLabel\",\"documentation\":\"invalidDocumentation\",\"parameters\":[{\"label\":\"test label\",\"documentation\":\"test documentation\"}]}],\"activeParameter\":1,\"activeSignature\":0}`\n\t)\n\twantType := SignatureHelp{\n\t\tSignatures: []SignatureInformation{\n\t\t\t{\n\t\t\t\tLabel:         \"testLabel\",\n\t\t\t\tDocumentation: \"testDocumentation\",\n\t\t\t\tParameters: []ParameterInformation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLabel:         \"test label\",\n\t\t\t\t\t\tDocumentation: \"test documentation\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tActiveParameter: 10,\n\t\tActiveSignature: 5,\n\t}\n\twantTypeNilAll := SignatureHelp{\n\t\tSignatures: []SignatureInformation{},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SignatureHelp\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SignatureHelp\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SignatureHelp\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSignatureInformation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"label\":\"testLabel\",\"documentation\":\"testDocumentation\",\"parameters\":[{\"label\":\"test label\",\"documentation\":\"test documentation\"}],\"activeParameter\":5}`\n\t\twantInvalid = `{\"label\":\"testLabel\",\"documentation\":\"invalidDocumentation\",\"parameters\":[{\"label\":\"test label\",\"documentation\":\"test documentation\"}],\"activeParameter\":50}`\n\t)\n\twantType := SignatureInformation{\n\t\tLabel:         \"testLabel\",\n\t\tDocumentation: \"testDocumentation\",\n\t\tParameters: []ParameterInformation{\n\t\t\t{\n\t\t\t\tLabel:         \"test label\",\n\t\t\t\tDocumentation: \"test documentation\",\n\t\t\t},\n\t\t},\n\t\tActiveParameter: uint32(5),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SignatureInformation\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SignatureInformation\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SignatureInformation\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestParameterInformation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"label\":\"test label\",\"documentation\":\"test documentation\"}`\n\t\twantInvalid = `{\"label\":\"invalid\",\"documentation\":\"invalid\"}`\n\t)\n\twantType := ParameterInformation{\n\t\tLabel:         \"test label\",\n\t\tDocumentation: \"test documentation\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ParameterInformation\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ParameterInformation\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ParameterInformation\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSignatureHelpRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"}],\"triggerCharacters\":[\".\"]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"triggerCharacters\":[\" \"]}`\n\t)\n\twantType := SignatureHelpRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tTriggerCharacters: []string{\".\"},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SignatureHelpRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SignatureHelpRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SignatureHelpRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestReferenceParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":25,\"character\":1},\"context\":{\"includeDeclaration\":true}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":2,\"character\":0},\"context\":{\"includeDeclaration\":false}}`\n\t)\n\twantType := ReferenceParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tContext: ReferenceContext{\n\t\t\tIncludeDeclaration: true,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ReferenceParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ReferenceParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ReferenceParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestReferenceContext(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"includeDeclaration\":true}`\n\t\twantInvalid = `{\"includeDeclaration\":false}`\n\t)\n\twantType := ReferenceContext{\n\t\tIncludeDeclaration: true,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ReferenceContext\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ReferenceContext\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ReferenceContext\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentHighlight(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"range\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}},\"kind\":1}`\n\t\twantInvalid = `{\"range\":{\"start\":{\"line\":25,\"character\":2},\"end\":{\"line\":25,\"character\":5}},\"kind\":1}`\n\t)\n\twantType := DocumentHighlight{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 4,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      255,\n\t\t\t\tCharacter: 10,\n\t\t\t},\n\t\t},\n\t\tKind: DocumentHighlightKindText,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentHighlight\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentHighlight\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentHighlight\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentHighlightKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    DocumentHighlightKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Text\",\n\t\t\tk:    DocumentHighlightKindText,\n\t\t\twant: \"Text\",\n\t\t},\n\t\t{\n\t\t\tname: \"Read\",\n\t\t\tk:    DocumentHighlightKindRead,\n\t\t\twant: \"Read\",\n\t\t},\n\t\t{\n\t\t\tname: \"Write\",\n\t\t\tk:    DocumentHighlightKindWrite,\n\t\t\twant: \"Write\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    DocumentHighlightKind(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"DocumentHighlightKind.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDocumentSymbolParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\twantType := DocumentSymbolParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/nottest.go\"}}`\n\t)\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentSymbolParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentSymbolParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentSymbolParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSymbolKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    SymbolKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"File\",\n\t\t\tk:    SymbolKindFile,\n\t\t\twant: \"File\",\n\t\t},\n\t\t{\n\t\t\tname: \"Module\",\n\t\t\tk:    SymbolKindModule,\n\t\t\twant: \"Module\",\n\t\t},\n\t\t{\n\t\t\tname: \"Namespace\",\n\t\t\tk:    SymbolKindNamespace,\n\t\t\twant: \"Namespace\",\n\t\t},\n\t\t{\n\t\t\tname: \"Package\",\n\t\t\tk:    SymbolKindPackage,\n\t\t\twant: \"Package\",\n\t\t},\n\t\t{\n\t\t\tname: \"Class\",\n\t\t\tk:    SymbolKindClass,\n\t\t\twant: \"Class\",\n\t\t},\n\t\t{\n\t\t\tname: \"Method\",\n\t\t\tk:    SymbolKindMethod,\n\t\t\twant: \"Method\",\n\t\t},\n\t\t{\n\t\t\tname: \"Property\",\n\t\t\tk:    SymbolKindProperty,\n\t\t\twant: \"Property\",\n\t\t},\n\t\t{\n\t\t\tname: \"Field\",\n\t\t\tk:    SymbolKindField,\n\t\t\twant: \"Field\",\n\t\t},\n\t\t{\n\t\t\tname: \"Constructor\",\n\t\t\tk:    SymbolKindConstructor,\n\t\t\twant: \"Constructor\",\n\t\t},\n\t\t{\n\t\t\tname: \"Enum\",\n\t\t\tk:    SymbolKindEnum,\n\t\t\twant: \"Enum\",\n\t\t},\n\t\t{\n\t\t\tname: \"Interface\",\n\t\t\tk:    SymbolKindInterface,\n\t\t\twant: \"Interface\",\n\t\t},\n\t\t{\n\t\t\tname: \"Function\",\n\t\t\tk:    SymbolKindFunction,\n\t\t\twant: \"Function\",\n\t\t},\n\t\t{\n\t\t\tname: \"Variable\",\n\t\t\tk:    SymbolKindVariable,\n\t\t\twant: \"Variable\",\n\t\t},\n\t\t{\n\t\t\tname: \"Constant\",\n\t\t\tk:    SymbolKindConstant,\n\t\t\twant: \"Constant\",\n\t\t},\n\t\t{\n\t\t\tname: \"String\",\n\t\t\tk:    SymbolKindString,\n\t\t\twant: \"String\",\n\t\t},\n\t\t{\n\t\t\tname: \"Number\",\n\t\t\tk:    SymbolKindNumber,\n\t\t\twant: \"Number\",\n\t\t},\n\t\t{\n\t\t\tname: \"Boolean\",\n\t\t\tk:    SymbolKindBoolean,\n\t\t\twant: \"Boolean\",\n\t\t},\n\t\t{\n\t\t\tname: \"Array\",\n\t\t\tk:    SymbolKindArray,\n\t\t\twant: \"Array\",\n\t\t},\n\t\t{\n\t\t\tname: \"Object\",\n\t\t\tk:    SymbolKindObject,\n\t\t\twant: \"Object\",\n\t\t},\n\t\t{\n\t\t\tname: \"Key\",\n\t\t\tk:    SymbolKindKey,\n\t\t\twant: \"Key\",\n\t\t},\n\t\t{\n\t\t\tname: \"Null\",\n\t\t\tk:    SymbolKindNull,\n\t\t\twant: \"Null\",\n\t\t},\n\t\t{\n\t\t\tname: \"EnumMember\",\n\t\t\tk:    SymbolKindEnumMember,\n\t\t\twant: \"EnumMember\",\n\t\t},\n\t\t{\n\t\t\tname: \"Struct\",\n\t\t\tk:    SymbolKindStruct,\n\t\t\twant: \"Struct\",\n\t\t},\n\t\t{\n\t\t\tname: \"Event\",\n\t\t\tk:    SymbolKindEvent,\n\t\t\twant: \"Event\",\n\t\t},\n\t\t{\n\t\t\tname: \"Operator\",\n\t\t\tk:    SymbolKindOperator,\n\t\t\twant: \"Operator\",\n\t\t},\n\t\t{\n\t\t\tname: \"TypeParameter\",\n\t\t\tk:    SymbolKindTypeParameter,\n\t\t\twant: \"TypeParameter\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    SymbolKind(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"SymbolKind.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSymbolTag_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    SymbolTag\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Deprecated\",\n\t\t\tk:    SymbolTagDeprecated,\n\t\t\twant: \"Deprecated\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    SymbolTag(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"SymbolTag.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDocumentSymbol(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"name\":\"test symbol\",\"detail\":\"test detail\",\"kind\":1,\"tags\":[1],\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":6}},\"selectionRange\":{\"start\":{\"line\":25,\"character\":3},\"end\":{\"line\":26,\"character\":10}},\"children\":[{\"name\":\"child symbol\",\"detail\":\"child detail\",\"kind\":11,\"deprecated\":true,\"range\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}},\"selectionRange\":{\"start\":{\"line\":255,\"character\":5},\"end\":{\"line\":255,\"character\":8}}}]}`\n\t\twantInvalid = `{\"name\":\"invalid symbol\",\"detail\":\"invalid detail\",\"kind\":1,\"tags\":[0],\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"selectionRange\":{\"start\":{\"line\":2,\"character\":5},\"end\":{\"line\":3,\"character\":1}},\"children\":[{\"name\":\"invalid child symbol\",\"kind\":1,\"detail\":\"invalid child detail\",\"range\":{\"start\":{\"line\":255,\"character\":4},\"end\":{\"line\":255,\"character\":10}},\"selectionRange\":{\"start\":{\"line\":255,\"character\":5},\"end\":{\"line\":255,\"character\":8}}}]}`\n\t)\n\twantType := DocumentSymbol{\n\t\tName:   \"test symbol\",\n\t\tDetail: \"test detail\",\n\t\tKind:   SymbolKindFile,\n\t\tTags: []SymbolTag{\n\t\t\tSymbolTagDeprecated,\n\t\t},\n\t\tDeprecated: false,\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 6,\n\t\t\t},\n\t\t},\n\t\tSelectionRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      26,\n\t\t\t\tCharacter: 10,\n\t\t\t},\n\t\t},\n\t\tChildren: []DocumentSymbol{\n\t\t\t{\n\t\t\t\tName:       \"child symbol\",\n\t\t\t\tDetail:     \"child detail\",\n\t\t\t\tKind:       SymbolKindInterface,\n\t\t\t\tDeprecated: true,\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 4,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 10,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSelectionRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 5,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      255,\n\t\t\t\t\t\tCharacter: 8,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentSymbol\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentSymbol\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentSymbol\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestSymbolInformation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"name\":\"test symbol\",\"kind\":1,\"tags\":[1],\"deprecated\":true,\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"containerName\":\"testContainerName\"}`\n\t\twantNilAll  = `{\"name\":\"test symbol\",\"kind\":1,\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}}`\n\t\twantInvalid = `{\"name\":\"invalid symbol\",\"kind\":1,\"tags\":[0],\"deprecated\":false,\"location\":{\"uri\":\"file:///path/to/test_test.go\",\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}},\"containerName\":\"invalidContainerName\"}`\n\t)\n\twantType := SymbolInformation{\n\t\tName: \"test symbol\",\n\t\tKind: 1,\n\t\tTags: []SymbolTag{\n\t\t\tSymbolTagDeprecated,\n\t\t},\n\t\tDeprecated: true,\n\t\tLocation: Location{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tContainerName: \"testContainerName\",\n\t}\n\twantTypeNilAll := SymbolInformation{\n\t\tName:       \"test symbol\",\n\t\tKind:       1,\n\t\tDeprecated: false,\n\t\tLocation: Location{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          SymbolInformation\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             SymbolInformation\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got SymbolInformation\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeActionParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"context\":{\"diagnostics\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"test.go\"}]}],\"only\":[\"quickfix\"]},\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":6}}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"context\":{\"diagnostics\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"test.go\"}]}],\"only\":[\"quickfix\"]},\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}}`\n\t)\n\twantType := CodeActionParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tContext: CodeActionContext{\n\t\t\tDiagnostics: []Diagnostic{\n\t\t\t\t{\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tSeverity: DiagnosticSeverityError,\n\t\t\t\t\tCode:     \"foo/bar\",\n\t\t\t\t\tSource:   \"test foo bar\",\n\t\t\t\t\tMessage:  \"foo bar\",\n\t\t\t\t\tRelatedInformation: []DiagnosticRelatedInformation{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLocation: Location{\n\t\t\t\t\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tMessage: \"test.go\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tOnly: []CodeActionKind{\n\t\t\t\tQuickFix,\n\t\t\t},\n\t\t},\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 6,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeActionParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeActionParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeActionParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeActionKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    CodeActionKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"QuickFix\",\n\t\t\tk:    QuickFix,\n\t\t\twant: \"quickfix\",\n\t\t},\n\t\t{\n\t\t\tname: \"Refactor\",\n\t\t\tk:    Refactor,\n\t\t\twant: \"refactor\",\n\t\t},\n\t\t{\n\t\t\tname: \"RefactorExtract\",\n\t\t\tk:    RefactorExtract,\n\t\t\twant: \"refactor.extract\",\n\t\t},\n\t\t{\n\t\t\tname: \"RefactorInline\",\n\t\t\tk:    RefactorInline,\n\t\t\twant: \"refactor.inline\",\n\t\t},\n\t\t{\n\t\t\tname: \"RefactorRewrite\",\n\t\t\tk:    RefactorRewrite,\n\t\t\twant: \"refactor.rewrite\",\n\t\t},\n\t\t{\n\t\t\tname: \"Source\",\n\t\t\tk:    Source,\n\t\t\twant: \"source\",\n\t\t},\n\t\t{\n\t\t\tname: \"SourceOrganizeImports\",\n\t\t\tk:    SourceOrganizeImports,\n\t\t\twant: \"source.organizeImports\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    CodeActionKind(\"\"),\n\t\t\twant: \"\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k; got != CodeActionKind(tt.want) {\n\t\t\t\tt.Errorf(\"CodeActionKind = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCodeActionContext(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"diagnostics\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"test.go\"}]}],\"only\":[\"quickfix\"]}`\n\t\twantInvalid = `{\"diagnostics\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"test.go\"}]}],\"only\":[\"quickfix\"]}`\n\t)\n\twantType := CodeActionContext{\n\t\tDiagnostics: []Diagnostic{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSeverity: DiagnosticSeverityError,\n\t\t\t\tCode:     \"foo/bar\",\n\t\t\t\tSource:   \"test foo bar\",\n\t\t\t\tMessage:  \"foo bar\",\n\t\t\t\tRelatedInformation: []DiagnosticRelatedInformation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLocation: Location{\n\t\t\t\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tMessage: \"test.go\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tOnly: []CodeActionKind{\n\t\t\tQuickFix,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeActionContext\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeActionContext\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeActionContext\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeAction(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"title\":\"Refactoring\",\"kind\":\"refactor.rewrite\",\"diagnostics\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"test.go\"}]}],\"isPreferred\":true,\"disabled\":{\"reason\":\"testReason\"},\"edit\":{\"changes\":{\"file:///path/to/test.go\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]},\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/test.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}]},\"command\":{\"title\":\"rewrite\",\"command\":\"rewriter\",\"arguments\":[\"-w\"]},\"data\":\"testData\"}`\n\t\twantInvalid = `{\"title\":\"Refactoring\",\"kind\":\"refactor\",\"diagnostics\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"severity\":1,\"code\":\"foo/bar\",\"source\":\"test foo bar\",\"message\":\"foo bar\",\"relatedInformation\":[{\"location\":{\"uri\":\"file:///path/to/test.go\",\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}},\"message\":\"test.go\"}]}],\"isPreferred\":false,\"disabled\":{\"reason\":\"invalidReason\"},\"edit\":{\"changes\":{\"file:///path/to/test.go\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\"}]},\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/test.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}]},\"command\":{\"title\":\"rewrite\",\"command\":\"rewriter\",\"arguments\":[\"-w\"]}}`\n\t)\n\twantType := CodeAction{\n\t\tTitle: \"Refactoring\",\n\t\tKind:  RefactorRewrite,\n\t\tDiagnostics: []Diagnostic{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSeverity: DiagnosticSeverityError,\n\t\t\t\tCode:     \"foo/bar\",\n\t\t\t\tSource:   \"test foo bar\",\n\t\t\t\tMessage:  \"foo bar\",\n\t\t\t\tRelatedInformation: []DiagnosticRelatedInformation{\n\t\t\t\t\t{\n\t\t\t\t\t\tLocation: Location{\n\t\t\t\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tMessage: \"test.go\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tIsPreferred: true,\n\t\tDisabled: &CodeActionDisable{\n\t\t\tReason: \"testReason\",\n\t\t},\n\t\tEdit: &WorkspaceEdit{\n\t\t\tChanges: map[uri.URI][]TextEdit{\n\t\t\t\turi.File(\"/path/to/test.go\"): {\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tDocumentChanges: []TextDocumentEdit{\n\t\t\t\t{\n\t\t\t\t\tTextDocument: OptionalVersionedTextDocumentIdentifier{\n\t\t\t\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tVersion: NewVersion(int32(10)),\n\t\t\t\t\t},\n\t\t\t\t\tEdits: []TextEdit{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tCommand: &Command{\n\t\t\tTitle:     \"rewrite\",\n\t\t\tCommand:   \"rewriter\",\n\t\t\tArguments: []any{\"-w\"},\n\t\t},\n\t\tData: \"testData\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeAction\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeAction\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeAction\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeActionRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}],\"codeActionKinds\":[\"quickfix\",\"refactor\"]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"},{\"language\":\"c\",\"scheme\":\"untitled\",\"pattern\":\"*.{c,h}\"}],\"codeActionKinds\":[\"quickfix\",\"refactor\"]}`\n\t)\n\twantType := CodeActionRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"cpp\",\n\t\t\t\t\tScheme:   \"untitled\",\n\t\t\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tCodeActionOptions: CodeActionOptions{\n\t\t\tCodeActionKinds: []CodeActionKind{\n\t\t\t\tQuickFix,\n\t\t\t\tRefactor,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeActionRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeActionRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeActionRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeLensParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"}}`\n\t)\n\twantType := CodeLensParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeLensParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeLensParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeLensParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeLens(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"command\":{\"title\":\"rewrite\",\"command\":\"rewriter\",\"arguments\":[\"-w\"]},\"data\":\"testData\"}`\n\t\twantNilAll  = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}`\n\t\twantInvalid = `{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"command\":{\"title\":\"rewrite\",\"command\":\"rewriter\",\"arguments\":[\"-w\"]},\"data\":\"invalidData\"}`\n\t)\n\twantType := CodeLens{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tCommand: &Command{\n\t\t\tTitle:     \"rewrite\",\n\t\t\tCommand:   \"rewriter\",\n\t\t\tArguments: []any{\"-w\"},\n\t\t},\n\t\tData: \"testData\",\n\t}\n\twantTypeNilAll := CodeLens{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeLens\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeLens\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeLens\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestCodeLensRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}],\"resolveProvider\":true}`\n\t\twantNilAll  = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"},{\"language\":\"c\",\"scheme\":\"untitled\",\"pattern\":\"*.{c,h}\"}],\"resolveProvider\":false}`\n\t)\n\twantType := CodeLensRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"cpp\",\n\t\t\t\t\tScheme:   \"untitled\",\n\t\t\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tResolveProvider: true,\n\t}\n\twantTypeNilAll := CodeLensRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"cpp\",\n\t\t\t\t\tScheme:   \"untitled\",\n\t\t\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          CodeLensRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             CodeLensRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got CodeLensRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentLinkParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"}}`\n\t)\n\twantType := DocumentLinkParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentLinkParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentLinkParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentLinkParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentLink(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"target\":\"file:///path/to/test.go\",\"tooltip\":\"testTooltip\",\"data\":\"testData\"}`\n\t\twantNilAll  = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}`\n\t\twantInvalid = `{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"target\":\"file:///path/to/test.go\",\"tooltip\":\"invalidTooltip\",\"data\":\"testData\"}`\n\t)\n\twantType := DocumentLink{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tTarget:  uri.File(\"/path/to/test.go\"),\n\t\tTooltip: \"testTooltip\",\n\t\tData:    \"testData\",\n\t}\n\twantTypeNilAll := DocumentLink{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentLink\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentLink\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentLink\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentColorParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"}}`\n\t)\n\twantType := DocumentColorParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentColorParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentColorParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentColorParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestColorInformation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"color\":{\"alpha\":1,\"blue\":0.2,\"green\":0.3,\"red\":0.4}}`\n\t\twantInvalid = `{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"color\":{\"alpha\":0,\"blue\":0.4,\"green\":0.3,\"red\":0.2}}`\n\t)\n\twantType := ColorInformation{\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tColor: Color{\n\t\t\tAlpha: 1,\n\t\t\tBlue:  0.2,\n\t\t\tGreen: 0.3,\n\t\t\tRed:   0.4,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ColorInformation\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ColorInformation\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ColorInformation\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestColor(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"alpha\":1,\"blue\":0.2,\"green\":0.3,\"red\":0.4}`\n\t\twantInvalid = `{\"alpha\":0,\"blue\":0.4,\"green\":0.3,\"red\":0.2}`\n\t)\n\twantType := Color{\n\t\tAlpha: 1,\n\t\tBlue:  0.2,\n\t\tGreen: 0.3,\n\t\tRed:   0.4,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Color\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Color\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Color\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestColorPresentationParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"color\":{\"alpha\":1,\"blue\":0.2,\"green\":0.3,\"red\":0.4},\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"color\":{\"alpha\":0,\"blue\":0.4,\"green\":0.3,\"red\":0.2},\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}}}`\n\t)\n\twantType := ColorPresentationParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tColor: Color{\n\t\t\tAlpha: 1,\n\t\t\tBlue:  0.2,\n\t\t\tGreen: 0.3,\n\t\t\tRed:   0.4,\n\t\t},\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ColorPresentationParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ColorPresentationParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ColorPresentationParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestColorPresentation(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"label\":\"testLabel\",\"textEdit\":{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"},\"additionalTextEdits\":[{\"range\":{\"start\":{\"line\":100,\"character\":10},\"end\":{\"line\":102,\"character\":15}},\"newText\":\"baz qux\"}]}`\n\t\twantNilAll  = `{\"label\":\"testLabel\"}`\n\t\twantInvalid = `{\"label\":\"invalidLabel\",\"textEdit\":{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"quux quuz\"},\"additionalTextEdits\":[{\"range\":{\"start\":{\"line\":105,\"character\":15},\"end\":{\"line\":107,\"character\":20}},\"newText\":\"corge grault\"}]}`\n\t)\n\twantType := ColorPresentation{\n\t\tLabel: \"testLabel\",\n\t\tTextEdit: &TextEdit{\n\t\t\tRange: Range{\n\t\t\t\tStart: Position{\n\t\t\t\t\tLine:      25,\n\t\t\t\t\tCharacter: 1,\n\t\t\t\t},\n\t\t\t\tEnd: Position{\n\t\t\t\t\tLine:      27,\n\t\t\t\t\tCharacter: 3,\n\t\t\t\t},\n\t\t\t},\n\t\t\tNewText: \"foo bar\",\n\t\t},\n\t\tAdditionalTextEdits: []TextEdit{\n\t\t\t{\n\t\t\t\tRange: Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      100,\n\t\t\t\t\t\tCharacter: 10,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      102,\n\t\t\t\t\t\tCharacter: 15,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNewText: \"baz qux\",\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := ColorPresentation{\n\t\tLabel: \"testLabel\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ColorPresentation\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ColorPresentation\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ColorPresentation\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentFormattingParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidWorkDoneToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"options\":{\"insertSpaces\":true,\"tabSize\":4},\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + invalidWorkDoneToken + `\",\"options\":{\"insertSpaces\":false,\"tabSize\":2},\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"}}`\n\t)\n\twantType := DocumentFormattingParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tOptions: FormattingOptions{\n\t\t\tInsertSpaces: true,\n\t\t\tTabSize:      4,\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentFormattingParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentFormattingParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentFormattingParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestFormattingOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"insertSpaces\":true,\"tabSize\":4,\"trimTrailingWhitespace\":true,\"insertFinalNewline\":true,\"trimFinalNewlines\":true,\"key\":{\"test\":\"key\"}}`\n\t\twantInvalid = `{\"insertSpaces\":false,\"tabSize\":2,\"trimTrailingWhitespace\":false,\"insertFinalNewline\":false,\"trimFinalNewlines\":false}`\n\t)\n\twantType := FormattingOptions{\n\t\tInsertSpaces:           true,\n\t\tTabSize:                4,\n\t\tTrimTrailingWhitespace: true,\n\t\tInsertFinalNewline:     true,\n\t\tTrimFinalNewlines:      true,\n\t\tKey: map[string]any{\n\t\t\t\"test\": \"key\",\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          FormattingOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             FormattingOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got FormattingOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentRangeFormattingParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidWorkDoneToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"options\":{\"insertSpaces\":true,\"tabSize\":4}}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + invalidWorkDoneToken + `\",\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"},\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"options\":{\"insertSpaces\":false,\"tabSize\":2}}`\n\t)\n\twantType := DocumentRangeFormattingParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tRange: Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      27,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tOptions: FormattingOptions{\n\t\t\tInsertSpaces: true,\n\t\t\tTabSize:      4,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentRangeFormattingParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentRangeFormattingParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentRangeFormattingParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentOnTypeFormattingParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":25,\"character\":1},\"ch\":\"character\",\"options\":{\"insertSpaces\":true,\"tabSize\":4}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"},\"position\":{\"line\":2,\"character\":1},\"ch\":\"invalidChar\",\"options\":{\"insertSpaces\":false,\"tabSize\":2}}`\n\t)\n\twantType := DocumentOnTypeFormattingParams{\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tPosition: Position{\n\t\t\tLine:      25,\n\t\t\tCharacter: 1,\n\t\t},\n\t\tCh: \"character\",\n\t\tOptions: FormattingOptions{\n\t\t\tInsertSpaces: true,\n\t\t\tTabSize:      4,\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentOnTypeFormattingParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentOnTypeFormattingParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentOnTypeFormattingParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDocumentOnTypeFormattingRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}],\"firstTriggerCharacter\":\"}\",\"moreTriggerCharacter\":[\".\",\"{\"]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"},{\"language\":\"c\",\"scheme\":\"untitled\",\"pattern\":\"*.{c,h}\"}],\"firstTriggerCharacter\":\"{\",\"moreTriggerCharacter\":[\" \",\"(\"]}`\n\t)\n\twantType := DocumentOnTypeFormattingRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"cpp\",\n\t\t\t\t\tScheme:   \"untitled\",\n\t\t\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tFirstTriggerCharacter: \"}\",\n\t\tMoreTriggerCharacter:  []string{\".\", \"{\"},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DocumentOnTypeFormattingRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DocumentOnTypeFormattingRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DocumentOnTypeFormattingRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRenameParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantPartialResultToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":25,\"character\":1},\"partialResultToken\":\"` + wantPartialResultToken + `\",\"newName\":\"newNameSymbol\"}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"},\"position\":{\"line\":2,\"character\":1},\"partialResultToken\":\"` + invalidPartialResultToken + `\",\"newName\":\"invalidSymbol\"}`\n\t)\n\twantType := RenameParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tNewName: \"newNameSymbol\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RenameParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RenameParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RenameParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRenameRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}],\"prepareProvider\":true}`\n\t\twantNilAll  = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"},{\"language\":\"c\",\"scheme\":\"untitled\",\"pattern\":\"*.{c,h}\"}],\"prepareProvider\":false}`\n\t)\n\twantType := RenameRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"cpp\",\n\t\t\t\t\tScheme:   \"untitled\",\n\t\t\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tPrepareProvider: true,\n\t}\n\twantTypeNilAll := RenameRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"cpp\",\n\t\t\t\t\tScheme:   \"untitled\",\n\t\t\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RenameRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RenameRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RenameRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestPrepareRenameParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":25,\"character\":1}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"},\"position\":{\"line\":2,\"character\":0}}`\n\t)\n\twantType := PrepareRenameParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          PrepareRenameParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             PrepareRenameParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got PrepareRenameParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestFoldingRangeParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantPartialResultToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"position\":{\"line\":25,\"character\":1},\"partialResultToken\":\"` + wantPartialResultToken + `\"}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"},\"position\":{\"line\":2,\"character\":0},\"partialResultToken\":\"` + invalidPartialResultToken + `\"}`\n\t)\n\twantType := FoldingRangeParams{\n\t\tTextDocumentPositionParams: TextDocumentPositionParams{\n\t\t\tTextDocument: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t},\n\t\t\tPosition: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          FoldingRangeParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             FoldingRangeParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got FoldingRangeParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestFoldingRangeKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\ts    FoldingRangeKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Comment\",\n\t\t\ts:    CommentFoldingRange,\n\t\t\twant: \"comment\",\n\t\t},\n\t\t{\n\t\t\tname: \"Imports\",\n\t\t\ts:    ImportsFoldingRange,\n\t\t\twant: \"imports\",\n\t\t},\n\t\t{\n\t\t\tname: \"Region\",\n\t\t\ts:    RegionFoldingRange,\n\t\t\twant: \"region\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\ts:    FoldingRangeKind(\"\"),\n\t\t\twant: \"\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.s; !strings.EqualFold(tt.want, string(got)) {\n\t\t\t\tt.Errorf(\"FoldingRangeKind(%v), want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestFoldingRange(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"startLine\":10,\"startCharacter\":1,\"endLine\":10,\"endCharacter\":8,\"kind\":\"imports\"}`\n\t\twantNilAll  = `{\"startLine\":10,\"endLine\":10}`\n\t\twantInvalid = `{\"startLine\":0,\"startCharacter\":1,\"endLine\":0,\"endCharacter\":8,\"kind\":\"comment\"}`\n\t)\n\twantType := FoldingRange{\n\t\tStartLine:      10,\n\t\tStartCharacter: 1,\n\t\tEndLine:        10,\n\t\tEndCharacter:   8,\n\t\tKind:           ImportsFoldingRange,\n\t}\n\twantTypeNilAll := FoldingRange{\n\t\tStartLine: 10,\n\t\tEndLine:   10,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          FoldingRange\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             FoldingRange\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got FoldingRange\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/progress.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// WorkDoneProgressKind kind of WorkDoneProgress.\n//\n// @since 3.15.0.\ntype WorkDoneProgressKind string\n\n// list of WorkDoneProgressKind.\nconst (\n\t// WorkDoneProgressKindBegin kind of WorkDoneProgressBegin.\n\tWorkDoneProgressKindBegin WorkDoneProgressKind = \"begin\"\n\n\t// WorkDoneProgressKindReport kind of WorkDoneProgressReport.\n\tWorkDoneProgressKindReport WorkDoneProgressKind = \"report\"\n\n\t// WorkDoneProgressKindEnd kind of WorkDoneProgressEnd.\n\tWorkDoneProgressKindEnd WorkDoneProgressKind = \"end\"\n)\n\n// WorkDoneProgressBegin is the to start progress reporting a \"$/progress\" notification.\n//\n// @since 3.15.0.\ntype WorkDoneProgressBegin struct {\n\t// Kind is the kind of WorkDoneProgressBegin.\n\t//\n\t// It must be WorkDoneProgressKindBegin.\n\tKind WorkDoneProgressKind `json:\"kind\"`\n\n\t// Title mandatory title of the progress operation. Used to briefly inform about\n\t// the kind of operation being performed.\n\t//\n\t// Examples: \"Indexing\" or \"Linking dependencies\".\n\tTitle string `json:\"title\"`\n\n\t// Cancellable controls if a cancel button should show to allow the user to cancel the\n\t// long running operation. Clients that don't support cancellation are allowed\n\t// to ignore the setting.\n\tCancellable bool `json:\"cancellable,omitempty\"`\n\n\t// Message is optional, more detailed associated progress message. Contains\n\t// complementary information to the `title`.\n\t//\n\t// Examples: \"3/25 files\", \"project/src/module2\", \"node_modules/some_dep\".\n\t// If unset, the previous progress message (if any) is still valid.\n\tMessage string `json:\"message,omitempty\"`\n\n\t// Percentage is optional progress percentage to display (value 100 is considered 100%).\n\t// If not provided infinite progress is assumed and clients are allowed\n\t// to ignore the `percentage` value in subsequent in report notifications.\n\t//\n\t// The value should be steadily rising. Clients are free to ignore values\n\t// that are not following this rule.\n\tPercentage uint32 `json:\"percentage,omitempty\"`\n}\n\n// WorkDoneProgressReport is the reporting progress is done.\n//\n// @since 3.15.0.\ntype WorkDoneProgressReport struct {\n\t// Kind is the kind of WorkDoneProgressReport.\n\t//\n\t// It must be WorkDoneProgressKindReport.\n\tKind WorkDoneProgressKind `json:\"kind\"`\n\n\t// Cancellable controls enablement state of a cancel button.\n\t//\n\t// Clients that don't support cancellation or don't support controlling the button's\n\t// enablement state are allowed to ignore the property.\n\tCancellable bool `json:\"cancellable,omitempty\"`\n\n\t// Message is optional, more detailed associated progress message. Contains\n\t// complementary information to the `title`.\n\t//\n\t// Examples: \"3/25 files\", \"project/src/module2\", \"node_modules/some_dep\".\n\t// If unset, the previous progress message (if any) is still valid.\n\tMessage string `json:\"message,omitempty\"`\n\n\t// Percentage is optional progress percentage to display (value 100 is considered 100%).\n\t// If not provided infinite progress is assumed and clients are allowed\n\t// to ignore the `percentage` value in subsequent in report notifications.\n\t//\n\t// The value should be steadily rising. Clients are free to ignore values\n\t// that are not following this rule.\n\tPercentage uint32 `json:\"percentage,omitempty\"`\n}\n\n// WorkDoneProgressEnd is the signaling the end of a progress reporting is done.\n//\n// @since 3.15.0.\ntype WorkDoneProgressEnd struct {\n\t// Kind is the kind of WorkDoneProgressEnd.\n\t//\n\t// It must be WorkDoneProgressKindEnd.\n\tKind WorkDoneProgressKind `json:\"kind\"`\n\n\t// Message is optional, a final message indicating to for example indicate the outcome\n\t// of the operation.\n\tMessage string `json:\"message,omitempty\"`\n}\n\n// WorkDoneProgressParams is a parameter property of report work done progress.\n//\n// @since 3.15.0.\ntype WorkDoneProgressParams struct {\n\t// WorkDoneToken an optional token that a server can use to report work done progress.\n\tWorkDoneToken *ProgressToken `json:\"workDoneToken,omitempty\"`\n}\n\n// PartialResultParams is the parameter literal used to pass a partial result token.\n//\n// @since 3.15.0.\ntype PartialResultParams struct {\n\t// PartialResultToken an optional token that a server can use to report partial results\n\t// (for example, streaming) to the client.\n\tPartialResultToken *ProgressToken `json:\"partialResultToken,omitempty\"`\n}\n"
  },
  {
    "path": "lsp/protocol/progress_test.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestWorkDoneProgressBegin(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"kind\":\"begin\",\"title\":\"testTitle\",\"cancellable\":true,\"message\":\"testMessage\",\"percentage\":30}`\n\t\twantNil     = `{\"kind\":\"begin\",\"title\":\"testTitle\"}`\n\t\twantInvalid = `{\"kind\":\"invalid\",\"title\":\"invalidTitle\",\"cancellable\":false,\"message\":\"invalidMessage\",\"percentage\":0}`\n\t)\n\twantType := WorkDoneProgressBegin{\n\t\tKind:        WorkDoneProgressKindBegin,\n\t\tTitle:       \"testTitle\",\n\t\tCancellable: true,\n\t\tMessage:     \"testMessage\",\n\t\tPercentage:  uint32(30),\n\t}\n\twantTypeNil := WorkDoneProgressBegin{\n\t\tKind:  WorkDoneProgressKindBegin,\n\t\tTitle: \"testTitle\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkDoneProgressBegin\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkDoneProgressBegin\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkDoneProgressBegin\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkDoneProgressReport(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"kind\":\"report\",\"cancellable\":true,\"message\":\"testMessage\",\"percentage\":30}`\n\t\twantNil     = `{\"kind\":\"report\"}`\n\t\twantInvalid = `{\"kind\":\"invalid\",\"cancellable\":false,\"message\":\"invalidMessage\",\"percentage\":0}`\n\t)\n\twantType := WorkDoneProgressReport{\n\t\tKind:        WorkDoneProgressKindReport,\n\t\tCancellable: true,\n\t\tMessage:     \"testMessage\",\n\t\tPercentage:  uint32(30),\n\t}\n\twantTypeNil := WorkDoneProgressReport{\n\t\tKind: WorkDoneProgressKindReport,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkDoneProgressReport\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkDoneProgressReport\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkDoneProgressReport\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkDoneProgressEnd(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"kind\":\"end\",\"message\":\"testMessage\"}`\n\t\twantNil     = `{\"kind\":\"end\"}`\n\t\twantInvalid = `{\"kind\":\"invalid\",\"message\":\"invalidMessage\"}`\n\t)\n\twantType := WorkDoneProgressEnd{\n\t\tKind:    WorkDoneProgressKindEnd,\n\t\tMessage: \"testMessage\",\n\t}\n\twantTypeNil := WorkDoneProgressEnd{\n\t\tKind: WorkDoneProgressKindEnd,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkDoneProgressEnd\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Nil\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkDoneProgressEnd\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Nil\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkDoneProgressEnd\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkDoneProgressParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst wantWorkDoneToken = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\tconst want = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\"}`\n\n\twantType := WorkDoneProgressParams{\n\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkDoneProgressParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkDoneProgressParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkDoneProgressParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestPartialResultParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst wantPartialResultParams = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\tconst want = `{\"partialResultToken\":\"` + wantPartialResultParams + `\"}`\n\n\twantType := PartialResultParams{\n\t\tPartialResultToken: NewProgressToken(wantPartialResultParams),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          PartialResultParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             PartialResultParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got PartialResultParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultParams); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/protocol.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n)\n\n// NewServer returns the context in which client is embedded, jsonrpc2.Conn, and the Client.\nfunc NewServer(ctx context.Context, server Server, stream jsonrpc2.Stream, logger *slog.Logger) (context.Context, jsonrpc2.Conn, Client) {\n\tconn := jsonrpc2.NewConn(stream)\n\tcliint := ClientDispatcher(conn, logger.With(slog.String(\"name\", \"client\")))\n\tctx = WithClient(ctx, cliint)\n\n\tconn.Go(ctx,\n\t\tHandlers(\n\t\t\tServerHandler(logger, server, jsonrpc2.MethodNotFoundHandler),\n\t\t),\n\t)\n\n\treturn ctx, conn, cliint\n}\n\n// NewClient returns the context in which Client is embedded, jsonrpc2.Conn, and the Server.\nfunc NewClient(ctx context.Context, client Client, stream jsonrpc2.Stream, logger *slog.Logger) (context.Context, jsonrpc2.Conn, Server) {\n\tctx = WithClient(ctx, client)\n\n\tconn := jsonrpc2.NewConn(stream)\n\tconn.Go(ctx,\n\t\tHandlers(\n\t\t\tClientHandler(logger, client, jsonrpc2.MethodNotFoundHandler),\n\t\t),\n\t)\n\tserver := ServerDispatcher(conn, logger.With(slog.String(\"name\", \"server\")))\n\n\treturn ctx, conn, server\n}\n"
  },
  {
    "path": "lsp/protocol/registration.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// Registration general parameters to register for a capability.\ntype Registration struct {\n\t// ID is the id used to register the request. The id can be used to deregister\n\t// the request again.\n\tID string `json:\"id\"`\n\n\t// Method is the method / capability to register for.\n\tMethod string `json:\"method\"`\n\n\t// RegisterOptions options necessary for the registration.\n\tRegisterOptions any `json:\"registerOptions,omitempty\"`\n}\n\n// RegistrationParams params of Register Capability.\ntype RegistrationParams struct {\n\tRegistrations []Registration `json:\"registrations\"`\n}\n\n// TextDocumentRegistrationOptions TextDocumentRegistration options.\ntype TextDocumentRegistrationOptions struct {\n\t// DocumentSelector a document selector to identify the scope of the registration. If set to null\n\t// the document selector provided on the client side will be used.\n\tDocumentSelector DocumentSelector `json:\"documentSelector\"`\n}\n\n// Unregistration general parameters to unregister a capability.\ntype Unregistration struct {\n\t// ID is the id used to unregister the request or notification. Usually an id\n\t// provided during the register request.\n\tID string `json:\"id\"`\n\n\t// Method is the method / capability to unregister for.\n\tMethod string `json:\"method\"`\n}\n\n// UnregistrationParams params of Unregistration.\ntype UnregistrationParams struct {\n\tUnregisterations []Unregistration `json:\"unregisterations\"`\n}\n"
  },
  {
    "path": "lsp/protocol/registration_test.go",
    "content": "// SPDX-FileCopyrightText: 2020 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestRegistration(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant           = `{\"id\":\"1\",\"method\":\"testMethod\",\"registerOptions\":{\"foo\":\"bar\"}}`\n\t\twantInterfaces = `{\"id\":\"1\",\"method\":\"testMethod\",\"registerOptions\":[\"foo\",\"bar\"]}`\n\t\twantNil        = `{\"id\":\"1\",\"method\":\"testMethod\"}`\n\t\twantInvalid    = `{\"id\":\"2\",\"method\":\"invalidMethod\",\"registerOptions\":{\"baz\":\"qux\"}}`\n\t)\n\twantTypeStringInterface := Registration{\n\t\tID:     \"1\",\n\t\tMethod: \"testMethod\",\n\t\tRegisterOptions: map[string]any{\n\t\t\t\"foo\": \"bar\",\n\t\t},\n\t}\n\twantTypeStringString := Registration{\n\t\tID:     \"1\",\n\t\tMethod: \"testMethod\",\n\t\tRegisterOptions: map[string]string{\n\t\t\t\"foo\": \"bar\",\n\t\t},\n\t}\n\twantTypeInterfaces := Registration{\n\t\tID:     \"1\",\n\t\tMethod: \"testMethod\",\n\t\tRegisterOptions: []any{\n\t\t\t\"foo\",\n\t\t\t\"bar\",\n\t\t},\n\t}\n\twantTypeNil := Registration{\n\t\tID:     \"1\",\n\t\tMethod: \"testMethod\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Registration\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"ValidStringInterface\",\n\t\t\t\tfield:          wantTypeStringInterface,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidStringString\",\n\t\t\t\tfield:          wantTypeStringString,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidInterfaces\",\n\t\t\t\tfield:          wantTypeInterfaces,\n\t\t\t\twant:           wantInterfaces,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantTypeStringInterface,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Registration\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"ValidStringInterface\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantTypeStringInterface,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidInterfaces\",\n\t\t\t\tfield:            wantInterfaces,\n\t\t\t\twant:             wantTypeInterfaces,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantTypeStringInterface,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Registration\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestRegistrationParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"registrations\":[{\"id\":\"1\",\"method\":\"testMethod\",\"registerOptions\":{\"foo\":\"bar\"}}]}`\n\t\twantNil     = `{\"registrations\":[{\"id\":\"1\",\"method\":\"testMethod\"}]}`\n\t\twantInvalid = `{\"registrations\":[{\"id\":\"2\",\"method\":\"invalidMethod\",\"registerOptions\":{\"baz\":\"qux\"}}]}`\n\t)\n\twantType := RegistrationParams{\n\t\tRegistrations: []Registration{\n\t\t\t{\n\t\t\t\tID:     \"1\",\n\t\t\t\tMethod: \"testMethod\",\n\t\t\t\tRegisterOptions: map[string]any{\n\t\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNil := RegistrationParams{\n\t\tRegistrations: []Registration{\n\t\t\t{\n\t\t\t\tID:     \"1\",\n\t\t\t\tMethod: \"testMethod\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          RegistrationParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNil,\n\t\t\t\twant:           wantNil,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             RegistrationParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNil,\n\t\t\t\twant:             wantTypeNil,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got RegistrationParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"},{\"language\":\"cpp\",\"scheme\":\"untitled\",\"pattern\":\"*.{cpp,hpp}\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"},{\"language\":\"c\",\"scheme\":\"untitled\",\"pattern\":\"*.{c,h}\"}]}`\n\t)\n\twantType := TextDocumentRegistrationOptions{\n\t\tDocumentSelector: DocumentSelector{\n\t\t\t{\n\t\t\t\tLanguage: \"go\",\n\t\t\t\tScheme:   \"file\",\n\t\t\t\tPattern:  \"*.go\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tLanguage: \"cpp\",\n\t\t\t\tScheme:   \"untitled\",\n\t\t\t\tPattern:  \"*.{cpp,hpp}\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestUnregistration(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"id\":\"1\",\"method\":\"testMethod\"}`\n\t\twantInvalid = `{\"id\":\"2\",\"method\":\"invalidMethod\"}`\n\t)\n\twantType := Unregistration{\n\t\tID:     \"1\",\n\t\tMethod: \"testMethod\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          Unregistration\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             Unregistration\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got Unregistration\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestUnregistrationParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"unregisterations\":[{\"id\":\"1\",\"method\":\"testMethod\"}]}`\n\t\twantInvalid = `{\"unregisterations\":[{\"id\":\"2\",\"method\":\"invalidMethod\"}]}`\n\t)\n\twantType := UnregistrationParams{\n\t\tUnregisterations: []Unregistration{\n\t\t\t{\n\t\t\t\tID:     \"1\",\n\t\t\t\tMethod: \"testMethod\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          UnregistrationParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             UnregistrationParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got UnregistrationParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/selectionrange.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// SelectionRangeProviderOptions selection range provider options interface.\ntype SelectionRangeProviderOptions any\n\n// SelectionRange represents a selection range represents a part of a selection hierarchy.\n//\n// A selection range may have a parent selection range that contains it.\n//\n// @since 3.15.0.\ntype SelectionRange struct {\n\t// Range is the Range of this selection range.\n\tRange Range `json:\"range\"`\n\n\t// Parent is the parent selection range containing this range. Therefore `parent.range` must contain this Range.\n\tParent *SelectionRange `json:\"parent,omitempty\"`\n}\n\n// EnableSelectionRange is the whether the selection range.\ntype EnableSelectionRange bool\n\n// compile time check whether the EnableSelectionRange implements a SelectionRangeProviderOptions interface.\nvar _ SelectionRangeProviderOptions = (*EnableSelectionRange)(nil)\n\n// Value implements SelectionRangeProviderOptions interface.\nfunc (v EnableSelectionRange) Value() any {\n\treturn bool(v)\n}\n\n// NewEnableSelectionRange returns the new EnableSelectionRange underlying types SelectionRangeProviderOptions.\nfunc NewEnableSelectionRange(enable bool) SelectionRangeProviderOptions {\n\tv := EnableSelectionRange(enable)\n\n\treturn &v\n}\n\n// SelectionRangeOptions is the server capability of selection range.\ntype SelectionRangeOptions struct {\n\tWorkDoneProgressOptions\n}\n\n// compile time check whether the EnableSelectionRange implements a SelectionRangeProviderOptions interface.\nvar _ SelectionRangeProviderOptions = (*EnableSelectionRange)(nil)\n\n// Value implements SelectionRangeProviderOptions interface.\nfunc (v *SelectionRangeOptions) Value() any {\n\treturn v\n}\n\n// NewSelectionRangeOptions returns the new SelectionRangeOptions underlying types SelectionRangeProviderOptions.\nfunc NewSelectionRangeOptions(enableWorkDoneProgress bool) SelectionRangeProviderOptions {\n\tv := SelectionRangeOptions{\n\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\tWorkDoneProgress: enableWorkDoneProgress,\n\t\t},\n\t}\n\n\treturn &v\n}\n\n// SelectionRangeRegistrationOptions is the server capability of selection range registration.\ntype SelectionRangeRegistrationOptions struct {\n\tSelectionRangeOptions\n\tTextDocumentRegistrationOptions\n\tStaticRegistrationOptions\n}\n\n// compile time check whether the SelectionRangeRegistrationOptions implements a SelectionRangeProviderOptions interface.\nvar _ SelectionRangeProviderOptions = (*SelectionRangeRegistrationOptions)(nil)\n\n// Value implements SelectionRangeProviderOptions interface.\nfunc (v *SelectionRangeRegistrationOptions) Value() any {\n\treturn v\n}\n\n// NewSelectionRangeRegistrationOptions returns the new SelectionRangeRegistrationOptions underlying types SelectionRangeProviderOptions.\nfunc NewSelectionRangeRegistrationOptions(enableWorkDoneProgress bool, selector DocumentSelector, id string) SelectionRangeProviderOptions {\n\tv := SelectionRangeRegistrationOptions{\n\t\tSelectionRangeOptions: SelectionRangeOptions{\n\t\t\tWorkDoneProgressOptions: WorkDoneProgressOptions{\n\t\t\t\tWorkDoneProgress: enableWorkDoneProgress,\n\t\t\t},\n\t\t},\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: selector,\n\t\t},\n\t\tStaticRegistrationOptions: StaticRegistrationOptions{\n\t\t\tID: id,\n\t\t},\n\t}\n\n\treturn &v\n}\n\n// SelectionRangeParams represents a parameter literal used in selection range requests.\n//\n// @since 3.15.0.\ntype SelectionRangeParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the text document.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Positions is the positions inside the text document.\n\tPositions []Position `json:\"positions\"`\n}\n"
  },
  {
    "path": "lsp/protocol/semantic_token.go",
    "content": "// SPDX-FileCopyrightText: 2021 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// SemanticTokenTypes represents a type of semantic token.\n//\n// @since 3.16.0.\ntype SemanticTokenTypes string\n\n// list of SemanticTokenTypes.\nconst (\n\tSemanticTokenNamespace SemanticTokenTypes = \"namespace\"\n\n\t// Represents a generic type. Acts as a fallback for types which\n\t// can't be mapped to a specific type like class or enum.\n\tSemanticTokenType          SemanticTokenTypes = \"type\"\n\tSemanticTokenClass         SemanticTokenTypes = \"class\"\n\tSemanticTokenEnum          SemanticTokenTypes = \"enum\"\n\tSemanticTokenInterface     SemanticTokenTypes = \"interface\"\n\tSemanticTokenStruct        SemanticTokenTypes = \"struct\"\n\tSemanticTokenTypeParameter SemanticTokenTypes = \"typeParameter\"\n\tSemanticTokenParameter     SemanticTokenTypes = \"parameter\"\n\tSemanticTokenVariable      SemanticTokenTypes = \"variable\"\n\tSemanticTokenProperty      SemanticTokenTypes = \"property\"\n\tSemanticTokenEnumMember    SemanticTokenTypes = \"enumMember\"\n\tSemanticTokenEvent         SemanticTokenTypes = \"event\"\n\tSemanticTokenFunction      SemanticTokenTypes = \"function\"\n\tSemanticTokenMethod        SemanticTokenTypes = \"method\"\n\tSemanticTokenMacro         SemanticTokenTypes = \"macro\"\n\tSemanticTokenKeyword       SemanticTokenTypes = \"keyword\"\n\tSemanticTokenModifier      SemanticTokenTypes = \"modifier\"\n\tSemanticTokenComment       SemanticTokenTypes = \"comment\"\n\tSemanticTokenString        SemanticTokenTypes = \"string\"\n\tSemanticTokenNumber        SemanticTokenTypes = \"number\"\n\tSemanticTokenRegexp        SemanticTokenTypes = \"regexp\"\n\tSemanticTokenOperator      SemanticTokenTypes = \"operator\"\n)\n\n// SemanticTokenModifiers represents a modifiers of semantic token.\n//\n// @since 3.16.0.\ntype SemanticTokenModifiers string\n\n// list of SemanticTokenModifiers.\nconst (\n\tSemanticTokenModifierDeclaration    SemanticTokenModifiers = \"declaration\"\n\tSemanticTokenModifierDefinition     SemanticTokenModifiers = \"definition\"\n\tSemanticTokenModifierReadonly       SemanticTokenModifiers = \"readonly\"\n\tSemanticTokenModifierStatic         SemanticTokenModifiers = \"static\"\n\tSemanticTokenModifierDeprecated     SemanticTokenModifiers = \"deprecated\"\n\tSemanticTokenModifierAbstract       SemanticTokenModifiers = \"abstract\"\n\tSemanticTokenModifierAsync          SemanticTokenModifiers = \"async\"\n\tSemanticTokenModifierModification   SemanticTokenModifiers = \"modification\"\n\tSemanticTokenModifierDocumentation  SemanticTokenModifiers = \"documentation\"\n\tSemanticTokenModifierDefaultLibrary SemanticTokenModifiers = \"defaultLibrary\"\n)\n\n// TokenFormat is an additional token format capability to allow future extensions of the format.\n//\n// @since 3.16.0.\ntype TokenFormat string\n\n// TokenFormatRelative described using relative positions.\nconst TokenFormatRelative TokenFormat = \"relative\"\n\n// SemanticTokensLegend is the on the capability level types and modifiers are defined using strings.\n//\n// However the real encoding happens using numbers.\n//\n// The server therefore needs to let the client know which numbers it is using for which types and modifiers.\n//\n// @since 3.16.0.\ntype SemanticTokensLegend struct {\n\t// TokenTypes is the token types a server uses.\n\tTokenTypes []SemanticTokenTypes `json:\"tokenTypes\"`\n\n\t// TokenModifiers is the token modifiers a server uses.\n\tTokenModifiers []SemanticTokenModifiers `json:\"tokenModifiers\"`\n}\n\n// SemanticTokensParams params for the SemanticTokensFull request.\n//\n// @since 3.16.0.\ntype SemanticTokensParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the text document.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n\n// SemanticTokens is the result of SemanticTokensFull request.\n//\n// @since 3.16.0.\ntype SemanticTokens struct {\n\t// ResultID an optional result id. If provided and clients support delta updating\n\t// the client will include the result id in the next semantic token request.\n\t//\n\t// A server can then instead of computing all semantic tokens again simply\n\t// send a delta.\n\tResultID string `json:\"resultId,omitempty\"`\n\n\t// Data is the actual tokens.\n\tData []uint32 `json:\"data\"`\n}\n\n// SemanticTokensPartialResult is the partial result of SemanticTokensFull request.\n//\n// @since 3.16.0.\ntype SemanticTokensPartialResult struct {\n\t// Data is the actual tokens.\n\tData []uint32 `json:\"data\"`\n}\n\n// SemanticTokensDeltaParams params for the SemanticTokensFullDelta request.\n//\n// @since 3.16.0.\ntype SemanticTokensDeltaParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the text document.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// PreviousResultID is the result id of a previous response.\n\t//\n\t// The result Id can either point to a full response or a delta response depending on what was received last.\n\tPreviousResultID string `json:\"previousResultId\"`\n}\n\n// SemanticTokensDelta result of SemanticTokensFullDelta request.\n//\n// @since 3.16.0.\ntype SemanticTokensDelta struct {\n\t// ResultID is the result id.\n\t//\n\t// This field is readonly.\n\tResultID string `json:\"resultId,omitempty\"`\n\n\t// Edits is the semantic token edits to transform a previous result into a new\n\t// result.\n\tEdits []SemanticTokensEdit `json:\"edits\"`\n}\n\n// SemanticTokensDeltaPartialResult is the partial result of SemanticTokensFullDelta request.\n//\n// @since 3.16.0.\ntype SemanticTokensDeltaPartialResult struct {\n\tEdits []SemanticTokensEdit `json:\"edits\"`\n}\n\n// SemanticTokensEdit is the semantic token edit.\n//\n// @since 3.16.0.\ntype SemanticTokensEdit struct {\n\t// Start is the start offset of the edit.\n\tStart uint32 `json:\"start\"`\n\n\t// DeleteCount is the count of elements to remove.\n\tDeleteCount uint32 `json:\"deleteCount\"`\n\n\t// Data is the elements to insert.\n\tData []uint32 `json:\"data,omitempty\"`\n}\n\n// SemanticTokensRangeParams params for the SemanticTokensRange request.\n//\n// @since 3.16.0.\ntype SemanticTokensRangeParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// TextDocument is the text document.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Range is the range the semantic tokens are requested for.\n\tRange Range `json:\"range\"`\n}\n"
  },
  {
    "path": "lsp/protocol/server.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\n\t\"encoding/json\"\n\n\t\"github.com/a-h/templ/lsp/jsonrpc2\"\n\t\"github.com/a-h/templ/lsp/xcontext\"\n)\n\n// ServerDispatcher returns a Server that dispatches LSP requests across the\n// given jsonrpc2 connection.\nfunc ServerDispatcher(conn jsonrpc2.Conn, logger *slog.Logger) Server {\n\treturn &server{\n\t\tConn:   conn,\n\t\tlogger: logger,\n\t}\n}\n\n// ServerHandler jsonrpc2.Handler of Language Server Prococol Server.\n//\n//nolint:unparam\nfunc ServerHandler(log *slog.Logger, server Server, handler jsonrpc2.Handler) jsonrpc2.Handler {\n\th := func(ctx context.Context, reply jsonrpc2.Replier, req jsonrpc2.Request) error {\n\t\tif ctx.Err() != nil {\n\t\t\txctx := xcontext.Detach(ctx)\n\n\t\t\treturn reply(xctx, nil, ErrRequestCancelled)\n\t\t}\n\t\thandled, err := serverDispatch(ctx, log, server, reply, req)\n\t\tif handled || err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// TODO: This code is wrong, it ignores handler and assumes non standard\n\t\t// request handles everything\n\t\t// non standard request should just be a layered handler.\n\t\tvar params any\n\t\tif err := json.Unmarshal(req.Params(), &params); err != nil {\n\t\t\treturn replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Request(ctx, req.Method(), params)\n\n\t\treturn reply(ctx, resp, err)\n\t}\n\n\treturn h\n}\n\n// serverDispatch implements jsonrpc2.Handler.\n//\n//nolint:gocognit,funlen,gocyclo,cyclop\nfunc serverDispatch(ctx context.Context, logger *slog.Logger, server Server, reply jsonrpc2.Replier, req jsonrpc2.Request) (handled bool, err error) {\n\tif ctx.Err() != nil {\n\t\treturn true, reply(ctx, nil, ErrRequestCancelled)\n\t}\n\n\tdec := json.NewDecoder(bytes.NewReader(req.Params()))\n\n\tswitch req.Method() {\n\tcase MethodInitialize: // request\n\t\tdefer logger.Debug(MethodInitialize, slog.Any(\"error\", err))\n\n\t\tvar params InitializeParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Initialize(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodInitialized: // notification\n\t\tdefer logger.Debug(MethodInitialized, slog.Any(\"error\", err))\n\n\t\tvar params InitializedParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.Initialized(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodShutdown: // request\n\t\tdefer logger.Debug(MethodShutdown, slog.Any(\"error\", err))\n\n\t\tif len(req.Params()) > 0 {\n\t\t\treturn true, reply(ctx, nil, fmt.Errorf(\"expected no params: %w\", jsonrpc2.ErrInvalidParams))\n\t\t}\n\n\t\terr := server.Shutdown(ctx)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodExit: // notification\n\t\tdefer logger.Debug(MethodExit, slog.Any(\"error\", err))\n\n\t\tif len(req.Params()) > 0 {\n\t\t\treturn true, reply(ctx, nil, fmt.Errorf(\"expected no params: %w\", jsonrpc2.ErrInvalidParams))\n\t\t}\n\n\t\terr := server.Exit(ctx)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWorkDoneProgressCancel: // notification\n\t\tdefer logger.Debug(MethodWorkDoneProgressCancel, slog.Any(\"error\", err))\n\n\t\tvar params WorkDoneProgressCancelParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.WorkDoneProgressCancel(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodLogTrace: // notification\n\t\tdefer logger.Debug(MethodLogTrace, slog.Any(\"error\", err))\n\n\t\tvar params LogTraceParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.LogTrace(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodSetTrace: // notification\n\t\tdefer logger.Debug(MethodSetTrace, slog.Any(\"error\", err))\n\n\t\tvar params SetTraceParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.SetTrace(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentCodeAction: // request\n\t\tdefer logger.Debug(MethodTextDocumentCodeAction, slog.Any(\"error\", err))\n\n\t\tvar params CodeActionParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.CodeAction(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentCodeLens: // request\n\t\tdefer logger.Debug(MethodTextDocumentCodeLens, slog.Any(\"error\", err))\n\n\t\tvar params CodeLensParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.CodeLens(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodCodeLensResolve: // request\n\t\tdefer logger.Debug(MethodCodeLensResolve, slog.Any(\"error\", err))\n\n\t\tvar params CodeLens\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.CodeLensResolve(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentColorPresentation: // request\n\t\tdefer logger.Debug(MethodTextDocumentColorPresentation, slog.Any(\"error\", err))\n\n\t\tvar params ColorPresentationParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.ColorPresentation(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentCompletion: // request\n\t\tdefer logger.Debug(MethodTextDocumentCompletion, slog.Any(\"error\", err))\n\n\t\tvar params CompletionParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Completion(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodCompletionItemResolve: // request\n\t\tdefer logger.Debug(MethodCompletionItemResolve, slog.Any(\"error\", err))\n\n\t\tvar params CompletionItem\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.CompletionResolve(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentDeclaration: // request\n\t\tdefer logger.Debug(MethodTextDocumentDeclaration, slog.Any(\"error\", err))\n\n\t\tvar params DeclarationParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Declaration(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentDefinition: // request\n\t\tdefer logger.Debug(MethodTextDocumentDefinition, slog.Any(\"error\", err))\n\n\t\tvar params DefinitionParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Definition(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentDidChange: // notification\n\t\tdefer logger.Debug(MethodTextDocumentDidChange, slog.Any(\"error\", err))\n\n\t\tvar params DidChangeTextDocumentParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidChange(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWorkspaceDidChangeConfiguration: // notification\n\t\tdefer logger.Debug(MethodWorkspaceDidChangeConfiguration, slog.Any(\"error\", err))\n\n\t\tvar params DidChangeConfigurationParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidChangeConfiguration(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWorkspaceDidChangeWatchedFiles: // notification\n\t\tdefer logger.Debug(MethodWorkspaceDidChangeWatchedFiles, slog.Any(\"error\", err))\n\n\t\tvar params DidChangeWatchedFilesParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidChangeWatchedFiles(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWorkspaceDidChangeWorkspaceFolders: // notification\n\t\tdefer logger.Debug(MethodWorkspaceDidChangeWorkspaceFolders, slog.Any(\"error\", err))\n\n\t\tvar params DidChangeWorkspaceFoldersParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidChangeWorkspaceFolders(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentDidClose: // notification\n\t\tdefer logger.Debug(MethodTextDocumentDidClose, slog.Any(\"error\", err))\n\n\t\tvar params DidCloseTextDocumentParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidClose(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentDidOpen: // notification\n\t\tdefer logger.Debug(MethodTextDocumentDidOpen, slog.Any(\"error\", err))\n\n\t\tvar params DidOpenTextDocumentParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidOpen(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentDidSave: // notification\n\t\tdefer logger.Debug(MethodTextDocumentDidSave, slog.Any(\"error\", err))\n\n\t\tvar params DidSaveTextDocumentParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidSave(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentDocumentColor: // request\n\t\tdefer logger.Debug(MethodTextDocumentDocumentColor, slog.Any(\"error\", err))\n\n\t\tvar params DocumentColorParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.DocumentColor(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentDocumentHighlight: // request\n\t\tdefer logger.Debug(MethodTextDocumentDocumentHighlight, slog.Any(\"error\", err))\n\n\t\tvar params DocumentHighlightParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.DocumentHighlight(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentDocumentLink: // request\n\t\tdefer logger.Debug(MethodTextDocumentDocumentLink, slog.Any(\"error\", err))\n\n\t\tvar params DocumentLinkParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.DocumentLink(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodDocumentLinkResolve: // request\n\t\tdefer logger.Debug(MethodDocumentLinkResolve, slog.Any(\"error\", err))\n\n\t\tvar params DocumentLink\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.DocumentLinkResolve(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentDocumentSymbol: // request\n\t\tdefer logger.Debug(MethodTextDocumentDocumentSymbol, slog.Any(\"error\", err))\n\n\t\tvar params DocumentSymbolParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.DocumentSymbol(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodWorkspaceExecuteCommand: // request\n\t\tdefer logger.Debug(MethodWorkspaceExecuteCommand, slog.Any(\"error\", err))\n\n\t\tvar params ExecuteCommandParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.ExecuteCommand(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentFoldingRange: // request\n\t\tdefer logger.Debug(MethodTextDocumentFoldingRange, slog.Any(\"error\", err))\n\n\t\tvar params FoldingRangeParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.FoldingRanges(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentFormatting: // request\n\t\tdefer logger.Debug(MethodTextDocumentFormatting, slog.Any(\"error\", err))\n\n\t\tvar params DocumentFormattingParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Formatting(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentHover: // request\n\t\tdefer logger.Debug(MethodTextDocumentHover, slog.Any(\"error\", err))\n\n\t\tvar params HoverParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Hover(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentImplementation: // request\n\t\tdefer logger.Debug(MethodTextDocumentImplementation, slog.Any(\"error\", err))\n\n\t\tvar params ImplementationParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Implementation(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentOnTypeFormatting: // request\n\t\tdefer logger.Debug(MethodTextDocumentOnTypeFormatting, slog.Any(\"error\", err))\n\n\t\tvar params DocumentOnTypeFormattingParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.OnTypeFormatting(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentPrepareRename: // request\n\t\tdefer logger.Debug(MethodTextDocumentPrepareRename, slog.Any(\"error\", err))\n\n\t\tvar params PrepareRenameParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.PrepareRename(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentRangeFormatting: // request\n\t\tdefer logger.Debug(MethodTextDocumentRangeFormatting, slog.Any(\"error\", err))\n\n\t\tvar params DocumentRangeFormattingParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.RangeFormatting(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentReferences: // request\n\t\tdefer logger.Debug(MethodTextDocumentReferences, slog.Any(\"error\", err))\n\n\t\tvar params ReferenceParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.References(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentRename: // request\n\t\tdefer logger.Debug(MethodTextDocumentRename, slog.Any(\"error\", err))\n\n\t\tvar params RenameParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Rename(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentSignatureHelp: // request\n\t\tdefer logger.Debug(MethodTextDocumentSignatureHelp, slog.Any(\"error\", err))\n\n\t\tvar params SignatureHelpParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.SignatureHelp(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodWorkspaceSymbol: // request\n\t\tdefer logger.Debug(MethodWorkspaceSymbol, slog.Any(\"error\", err))\n\n\t\tvar params WorkspaceSymbolParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Symbols(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentTypeDefinition: // request\n\t\tdefer logger.Debug(MethodTextDocumentTypeDefinition, slog.Any(\"error\", err))\n\n\t\tvar params TypeDefinitionParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.TypeDefinition(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodTextDocumentWillSave: // notification\n\t\tdefer logger.Debug(MethodTextDocumentWillSave, slog.Any(\"error\", err))\n\n\t\tvar params WillSaveTextDocumentParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.WillSave(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentWillSaveWaitUntil: // request\n\t\tdefer logger.Debug(MethodTextDocumentWillSaveWaitUntil, slog.Any(\"error\", err))\n\n\t\tvar params WillSaveTextDocumentParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.WillSaveWaitUntil(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodShowDocument: // request\n\t\tdefer logger.Debug(MethodShowDocument, slog.Any(\"error\", err))\n\n\t\tvar params ShowDocumentParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.ShowDocument(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodWillCreateFiles: // request\n\t\tdefer logger.Debug(MethodWillCreateFiles, slog.Any(\"error\", err))\n\n\t\tvar params CreateFilesParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.WillCreateFiles(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodDidCreateFiles: // notification\n\t\tdefer logger.Debug(MethodDidCreateFiles, slog.Any(\"error\", err))\n\n\t\tvar params CreateFilesParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidCreateFiles(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWillRenameFiles: // request\n\t\tdefer logger.Debug(MethodWillRenameFiles, slog.Any(\"error\", err))\n\n\t\tvar params RenameFilesParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.WillRenameFiles(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodDidRenameFiles: // notification\n\t\tdefer logger.Debug(MethodDidRenameFiles, slog.Any(\"error\", err))\n\n\t\tvar params RenameFilesParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidRenameFiles(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodWillDeleteFiles: // request\n\t\tdefer logger.Debug(MethodWillDeleteFiles, slog.Any(\"error\", err))\n\n\t\tvar params DeleteFilesParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.WillDeleteFiles(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodDidDeleteFiles: // notification\n\t\tdefer logger.Debug(MethodDidDeleteFiles, slog.Any(\"error\", err))\n\n\t\tvar params DeleteFilesParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\terr := server.DidDeleteFiles(ctx, &params)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodCodeLensRefresh: // request\n\t\tdefer logger.Debug(MethodCodeLensRefresh, slog.Any(\"error\", err))\n\n\t\tif len(req.Params()) > 0 {\n\t\t\treturn true, reply(ctx, nil, fmt.Errorf(\"expected no params: %w\", jsonrpc2.ErrInvalidParams))\n\t\t}\n\n\t\terr := server.CodeLensRefresh(ctx)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodTextDocumentPrepareCallHierarchy: // request\n\t\tdefer logger.Debug(MethodTextDocumentPrepareCallHierarchy, slog.Any(\"error\", err))\n\n\t\tvar params CallHierarchyPrepareParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.PrepareCallHierarchy(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodCallHierarchyIncomingCalls: // request\n\t\tdefer logger.Debug(MethodCallHierarchyIncomingCalls, slog.Any(\"error\", err))\n\n\t\tvar params CallHierarchyIncomingCallsParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.IncomingCalls(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodCallHierarchyOutgoingCalls: // request\n\t\tdefer logger.Debug(MethodCallHierarchyOutgoingCalls, slog.Any(\"error\", err))\n\n\t\tvar params CallHierarchyOutgoingCallsParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.OutgoingCalls(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodSemanticTokensFull: // request\n\t\tdefer logger.Debug(MethodSemanticTokensFull, slog.Any(\"error\", err))\n\n\t\tvar params SemanticTokensParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.SemanticTokensFull(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodSemanticTokensFullDelta: // request\n\t\tdefer logger.Debug(MethodSemanticTokensFullDelta, slog.Any(\"error\", err))\n\n\t\tvar params SemanticTokensDeltaParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.SemanticTokensFullDelta(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodSemanticTokensRange: // request\n\t\tdefer logger.Debug(MethodSemanticTokensRange, slog.Any(\"error\", err))\n\n\t\tvar params SemanticTokensRangeParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.SemanticTokensRange(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodSemanticTokensRefresh: // request\n\t\tdefer logger.Debug(MethodSemanticTokensRefresh, slog.Any(\"error\", err))\n\n\t\tif len(req.Params()) > 0 {\n\t\t\treturn true, reply(ctx, nil, fmt.Errorf(\"expected no params: %w\", jsonrpc2.ErrInvalidParams))\n\t\t}\n\n\t\terr := server.SemanticTokensRefresh(ctx)\n\n\t\treturn true, reply(ctx, nil, err)\n\n\tcase MethodLinkedEditingRange: // request\n\t\tdefer logger.Debug(MethodLinkedEditingRange, slog.Any(\"error\", err))\n\n\t\tvar params LinkedEditingRangeParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.LinkedEditingRange(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tcase MethodMoniker: // request\n\t\tdefer logger.Debug(MethodMoniker, slog.Any(\"error\", err))\n\n\t\tvar params MonikerParams\n\t\tif err := dec.Decode(&params); err != nil {\n\t\t\treturn true, replyParseError(ctx, reply, err)\n\t\t}\n\n\t\tresp, err := server.Moniker(ctx, &params)\n\n\t\treturn true, reply(ctx, resp, err)\n\n\tdefault:\n\t\treturn false, nil\n\t}\n}\n\n// Server represents a Language Server Protocol server.\ntype Server interface {\n\tInitialize(ctx context.Context, params *InitializeParams) (result *InitializeResult, err error)\n\tInitialized(ctx context.Context, params *InitializedParams) (err error)\n\tShutdown(ctx context.Context) (err error)\n\tExit(ctx context.Context) (err error)\n\tWorkDoneProgressCancel(ctx context.Context, params *WorkDoneProgressCancelParams) (err error)\n\tLogTrace(ctx context.Context, params *LogTraceParams) (err error)\n\tSetTrace(ctx context.Context, params *SetTraceParams) (err error)\n\tCodeAction(ctx context.Context, params *CodeActionParams) (result []CodeAction, err error)\n\tCodeLens(ctx context.Context, params *CodeLensParams) (result []CodeLens, err error)\n\tCodeLensResolve(ctx context.Context, params *CodeLens) (result *CodeLens, err error)\n\tColorPresentation(ctx context.Context, params *ColorPresentationParams) (result []ColorPresentation, err error)\n\tCompletion(ctx context.Context, params *CompletionParams) (result *CompletionList, err error)\n\tCompletionResolve(ctx context.Context, params *CompletionItem) (result *CompletionItem, err error)\n\tDeclaration(ctx context.Context, params *DeclarationParams) (result []Location /* Declaration | DeclarationLink[] | null */, err error)\n\tDefinition(ctx context.Context, params *DefinitionParams) (result []Location /* Definition | DefinitionLink[] | null */, err error)\n\tDidChange(ctx context.Context, params *DidChangeTextDocumentParams) (err error)\n\tDidChangeConfiguration(ctx context.Context, params *DidChangeConfigurationParams) (err error)\n\tDidChangeWatchedFiles(ctx context.Context, params *DidChangeWatchedFilesParams) (err error)\n\tDidChangeWorkspaceFolders(ctx context.Context, params *DidChangeWorkspaceFoldersParams) (err error)\n\tDidClose(ctx context.Context, params *DidCloseTextDocumentParams) (err error)\n\tDidOpen(ctx context.Context, params *DidOpenTextDocumentParams) (err error)\n\tDidSave(ctx context.Context, params *DidSaveTextDocumentParams) (err error)\n\tDocumentColor(ctx context.Context, params *DocumentColorParams) (result []ColorInformation, err error)\n\tDocumentHighlight(ctx context.Context, params *DocumentHighlightParams) (result []DocumentHighlight, err error)\n\tDocumentLink(ctx context.Context, params *DocumentLinkParams) (result []DocumentLink, err error)\n\tDocumentLinkResolve(ctx context.Context, params *DocumentLink) (result *DocumentLink, err error)\n\tDocumentSymbol(ctx context.Context, params *DocumentSymbolParams) (result []SymbolInformationOrDocumentSymbol, err error)\n\tExecuteCommand(ctx context.Context, params *ExecuteCommandParams) (result any, err error)\n\tFoldingRanges(ctx context.Context, params *FoldingRangeParams) (result []FoldingRange, err error)\n\tFormatting(ctx context.Context, params *DocumentFormattingParams) (result []TextEdit, err error)\n\tHover(ctx context.Context, params *HoverParams) (result *Hover, err error)\n\tImplementation(ctx context.Context, params *ImplementationParams) (result []Location, err error)\n\tOnTypeFormatting(ctx context.Context, params *DocumentOnTypeFormattingParams) (result []TextEdit, err error)\n\tPrepareRename(ctx context.Context, params *PrepareRenameParams) (result *Range, err error)\n\tRangeFormatting(ctx context.Context, params *DocumentRangeFormattingParams) (result []TextEdit, err error)\n\tReferences(ctx context.Context, params *ReferenceParams) (result []Location, err error)\n\tRename(ctx context.Context, params *RenameParams) (result *WorkspaceEdit, err error)\n\tSignatureHelp(ctx context.Context, params *SignatureHelpParams) (result *SignatureHelp, err error)\n\tSymbols(ctx context.Context, params *WorkspaceSymbolParams) (result []SymbolInformation, err error)\n\tTypeDefinition(ctx context.Context, params *TypeDefinitionParams) (result []Location, err error)\n\tWillSave(ctx context.Context, params *WillSaveTextDocumentParams) (err error)\n\tWillSaveWaitUntil(ctx context.Context, params *WillSaveTextDocumentParams) (result []TextEdit, err error)\n\tShowDocument(ctx context.Context, params *ShowDocumentParams) (result *ShowDocumentResult, err error)\n\tWillCreateFiles(ctx context.Context, params *CreateFilesParams) (result *WorkspaceEdit, err error)\n\tDidCreateFiles(ctx context.Context, params *CreateFilesParams) (err error)\n\tWillRenameFiles(ctx context.Context, params *RenameFilesParams) (result *WorkspaceEdit, err error)\n\tDidRenameFiles(ctx context.Context, params *RenameFilesParams) (err error)\n\tWillDeleteFiles(ctx context.Context, params *DeleteFilesParams) (result *WorkspaceEdit, err error)\n\tDidDeleteFiles(ctx context.Context, params *DeleteFilesParams) (err error)\n\tCodeLensRefresh(ctx context.Context) (err error)\n\tPrepareCallHierarchy(ctx context.Context, params *CallHierarchyPrepareParams) (result []CallHierarchyItem, err error)\n\tIncomingCalls(ctx context.Context, params *CallHierarchyIncomingCallsParams) (result []CallHierarchyIncomingCall, err error)\n\tOutgoingCalls(ctx context.Context, params *CallHierarchyOutgoingCallsParams) (result []CallHierarchyOutgoingCall, err error)\n\tSemanticTokensFull(ctx context.Context, params *SemanticTokensParams) (result *SemanticTokens, err error)\n\tSemanticTokensFullDelta(ctx context.Context, params *SemanticTokensDeltaParams) (result any /* SemanticTokens | SemanticTokensDelta */, err error)\n\tSemanticTokensRange(ctx context.Context, params *SemanticTokensRangeParams) (result *SemanticTokens, err error)\n\tSemanticTokensRefresh(ctx context.Context) (err error)\n\tLinkedEditingRange(ctx context.Context, params *LinkedEditingRangeParams) (result *LinkedEditingRanges, err error)\n\tMoniker(ctx context.Context, params *MonikerParams) (result []Moniker, err error)\n\tRequest(ctx context.Context, method string, params any) (result any, err error)\n}\n\n// list of server methods.\nconst (\n\t// MethodCancelRequest method name of \"$/cancelRequest\".\n\tMethodCancelRequest = \"$/cancelRequest\"\n\n\t// MethodInitialize method name of \"initialize\".\n\tMethodInitialize = \"initialize\"\n\n\t// MethodInitialized method name of \"initialized\".\n\tMethodInitialized = \"initialized\"\n\n\t// MethodShutdown method name of \"shutdown\".\n\tMethodShutdown = \"shutdown\"\n\n\t// MethodExit method name of \"exit\".\n\tMethodExit = \"exit\"\n\n\t// MethodWorkDoneProgressCancel method name of \"window/workDoneProgress/cancel\".\n\tMethodWorkDoneProgressCancel = \"window/workDoneProgress/cancel\"\n\n\t// MethodLogTrace method name of \"$/logTrace\".\n\tMethodLogTrace = \"$/logTrace\"\n\n\t// MethodSetTrace method name of \"$/setTrace\".\n\tMethodSetTrace = \"$/setTrace\"\n\n\t// MethodTextDocumentCodeAction method name of \"textDocument/codeAction\".\n\tMethodTextDocumentCodeAction = \"textDocument/codeAction\"\n\n\t// MethodTextDocumentCodeLens method name of \"textDocument/codeLens\".\n\tMethodTextDocumentCodeLens = \"textDocument/codeLens\"\n\n\t// MethodCodeLensResolve method name of \"codeLens/resolve\".\n\tMethodCodeLensResolve = \"codeLens/resolve\"\n\n\t// MethodTextDocumentColorPresentation method name of \"textDocument/colorPresentation\".\n\tMethodTextDocumentColorPresentation = \"textDocument/colorPresentation\"\n\n\t// MethodTextDocumentCompletion method name of \"textDocument/completion\".\n\tMethodTextDocumentCompletion = \"textDocument/completion\"\n\n\t// MethodCompletionItemResolve method name of \"completionItem/resolve\".\n\tMethodCompletionItemResolve = \"completionItem/resolve\"\n\n\t// MethodTextDocumentDeclaration method name of \"textDocument/declaration\".\n\tMethodTextDocumentDeclaration = \"textDocument/declaration\"\n\n\t// MethodTextDocumentDefinition method name of \"textDocument/definition\".\n\tMethodTextDocumentDefinition = \"textDocument/definition\"\n\n\t// MethodTextDocumentDidChange method name of \"textDocument/didChange\".\n\tMethodTextDocumentDidChange = \"textDocument/didChange\"\n\n\t// MethodWorkspaceDidChangeConfiguration method name of \"workspace/didChangeConfiguration\".\n\tMethodWorkspaceDidChangeConfiguration = \"workspace/didChangeConfiguration\"\n\n\t// MethodWorkspaceDidChangeWatchedFiles method name of \"workspace/didChangeWatchedFiles\".\n\tMethodWorkspaceDidChangeWatchedFiles = \"workspace/didChangeWatchedFiles\"\n\n\t// MethodWorkspaceDidChangeWorkspaceFolders method name of \"workspace/didChangeWorkspaceFolders\".\n\tMethodWorkspaceDidChangeWorkspaceFolders = \"workspace/didChangeWorkspaceFolders\"\n\n\t// MethodTextDocumentDidClose method name of \"textDocument/didClose\".\n\tMethodTextDocumentDidClose = \"textDocument/didClose\"\n\n\t// MethodTextDocumentDidOpen method name of \"textDocument/didOpen\".\n\tMethodTextDocumentDidOpen = \"textDocument/didOpen\"\n\n\t// MethodTextDocumentDidSave method name of \"textDocument/didSave\".\n\tMethodTextDocumentDidSave = \"textDocument/didSave\"\n\n\t// MethodTextDocumentDocumentColor method name of\"textDocument/documentColor\".\n\tMethodTextDocumentDocumentColor = \"textDocument/documentColor\"\n\n\t// MethodTextDocumentDocumentHighlight method name of \"textDocument/documentHighlight\".\n\tMethodTextDocumentDocumentHighlight = \"textDocument/documentHighlight\"\n\n\t// MethodTextDocumentDocumentLink method name of \"textDocument/documentLink\".\n\tMethodTextDocumentDocumentLink = \"textDocument/documentLink\"\n\n\t// MethodDocumentLinkResolve method name of \"documentLink/resolve\".\n\tMethodDocumentLinkResolve = \"documentLink/resolve\"\n\n\t// MethodTextDocumentDocumentSymbol method name of \"textDocument/documentSymbol\".\n\tMethodTextDocumentDocumentSymbol = \"textDocument/documentSymbol\"\n\n\t// MethodWorkspaceExecuteCommand method name of \"workspace/executeCommand\".\n\tMethodWorkspaceExecuteCommand = \"workspace/executeCommand\"\n\n\t// MethodTextDocumentFoldingRange method name of \"textDocument/foldingRange\".\n\tMethodTextDocumentFoldingRange = \"textDocument/foldingRange\"\n\n\t// MethodTextDocumentFormatting method name of \"textDocument/formatting\".\n\tMethodTextDocumentFormatting = \"textDocument/formatting\"\n\n\t// MethodTextDocumentHover method name of \"textDocument/hover\".\n\tMethodTextDocumentHover = \"textDocument/hover\"\n\n\t// MethodTextDocumentImplementation method name of \"textDocument/implementation\".\n\tMethodTextDocumentImplementation = \"textDocument/implementation\"\n\n\t// MethodTextDocumentOnTypeFormatting method name of \"textDocument/onTypeFormatting\".\n\tMethodTextDocumentOnTypeFormatting = \"textDocument/onTypeFormatting\"\n\n\t// MethodTextDocumentPrepareRename method name of \"textDocument/prepareRename\".\n\tMethodTextDocumentPrepareRename = \"textDocument/prepareRename\"\n\n\t// MethodTextDocumentRangeFormatting method name of \"textDocument/rangeFormatting\".\n\tMethodTextDocumentRangeFormatting = \"textDocument/rangeFormatting\"\n\n\t// MethodTextDocumentReferences method name of \"textDocument/references\".\n\tMethodTextDocumentReferences = \"textDocument/references\"\n\n\t// MethodTextDocumentRename method name of \"textDocument/rename\".\n\tMethodTextDocumentRename = \"textDocument/rename\"\n\n\t// MethodTextDocumentSignatureHelp method name of \"textDocument/signatureHelp\".\n\tMethodTextDocumentSignatureHelp = \"textDocument/signatureHelp\"\n\n\t// MethodWorkspaceSymbol method name of \"workspace/symbol\".\n\tMethodWorkspaceSymbol = \"workspace/symbol\"\n\n\t// MethodTextDocumentTypeDefinition method name of \"textDocument/typeDefinition\".\n\tMethodTextDocumentTypeDefinition = \"textDocument/typeDefinition\"\n\n\t// MethodTextDocumentWillSave method name of \"textDocument/willSave\".\n\tMethodTextDocumentWillSave = \"textDocument/willSave\"\n\n\t// MethodTextDocumentWillSaveWaitUntil method name of \"textDocument/willSaveWaitUntil\".\n\tMethodTextDocumentWillSaveWaitUntil = \"textDocument/willSaveWaitUntil\"\n\n\t// MethodShowDocument method name of \"window/showDocument\".\n\tMethodShowDocument = \"window/showDocument\"\n\n\t// MethodWillCreateFiles method name of \"workspace/willCreateFiles\".\n\tMethodWillCreateFiles = \"workspace/willCreateFiles\"\n\n\t// MethodDidCreateFiles method name of \"workspace/didCreateFiles\".\n\tMethodDidCreateFiles = \"workspace/didCreateFiles\"\n\n\t// MethodWillRenameFiles method name of \"workspace/willRenameFiles\".\n\tMethodWillRenameFiles = \"workspace/willRenameFiles\"\n\n\t// MethodDidRenameFiles method name of \"workspace/didRenameFiles\".\n\tMethodDidRenameFiles = \"workspace/didRenameFiles\"\n\n\t// MethodWillDeleteFiles method name of \"workspace/willDeleteFiles\".\n\tMethodWillDeleteFiles = \"workspace/willDeleteFiles\"\n\n\t// MethodDidDeleteFiles method name of \"workspace/didDeleteFiles\".\n\tMethodDidDeleteFiles = \"workspace/didDeleteFiles\"\n\n\t// MethodCodeLensRefresh method name of \"workspace/codeLens/refresh\".\n\tMethodCodeLensRefresh = \"workspace/codeLens/refresh\"\n\n\t// MethodTextDocumentPrepareCallHierarchy method name of \"textDocument/prepareCallHierarchy\".\n\tMethodTextDocumentPrepareCallHierarchy = \"textDocument/prepareCallHierarchy\"\n\n\t// MethodCallHierarchyIncomingCalls method name of \"callHierarchy/incomingCalls\".\n\tMethodCallHierarchyIncomingCalls = \"callHierarchy/incomingCalls\"\n\n\t// MethodCallHierarchyOutgoingCalls method name of \"callHierarchy/outgoingCalls\".\n\tMethodCallHierarchyOutgoingCalls = \"callHierarchy/outgoingCalls\"\n\n\t// MethodSemanticTokensFull method name of \"textDocument/semanticTokens/full\".\n\tMethodSemanticTokensFull = \"textDocument/semanticTokens/full\"\n\n\t// MethodSemanticTokensFullDelta method name of \"textDocument/semanticTokens/full/delta\".\n\tMethodSemanticTokensFullDelta = \"textDocument/semanticTokens/full/delta\"\n\n\t// MethodSemanticTokensRange method name of \"textDocument/semanticTokens/range\".\n\tMethodSemanticTokensRange = \"textDocument/semanticTokens/range\"\n\n\t// MethodSemanticTokensRefresh method name of \"workspace/semanticTokens/refresh\".\n\tMethodSemanticTokensRefresh = \"workspace/semanticTokens/refresh\"\n\n\t// MethodLinkedEditingRange method name of \"textDocument/linkedEditingRange\".\n\tMethodLinkedEditingRange = \"textDocument/linkedEditingRange\"\n\n\t// MethodMoniker method name of \"textDocument/moniker\".\n\tMethodMoniker = \"textDocument/moniker\"\n)\n\n// server implements a Language Server Protocol server.\ntype server struct {\n\tjsonrpc2.Conn\n\n\tlogger *slog.Logger\n}\n\nvar _ Server = (*server)(nil)\n\n// Initialize sents the request as the first request from the client to the server.\n//\n// If the server receives a request or notification before the initialize request it should act as follows:\n//\n// - For a request the response should be an error with code: -32002. The message can be picked by the server.\n// - Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request.\n//\n// Until the server has responded to the initialize request with an InitializeResult, the client\n// must not send any additional requests or notifications to the server.\n// In addition the server is not allowed to send any requests or notifications to the client until\n// it has responded with an InitializeResult, with the exception that during the initialize request\n// the server is allowed to send the notifications window/showMessage, window/logMessage and telemetry/event\n// as well as the window/showMessageRequest request to the client.\nfunc (s *server) Initialize(ctx context.Context, params *InitializeParams) (_ *InitializeResult, err error) {\n\ts.logger.Debug(\"call \" + MethodInitialize)\n\tdefer s.logger.Debug(\"end \"+MethodInitialize, slog.Any(\"error\", err))\n\n\tvar result *InitializeResult\n\tif err := Call(ctx, s.Conn, MethodInitialize, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Initialized sends the notification from the client to the server after the client received the result of the\n// initialize request but before the client is sending any other request or notification to the server.\n//\n// The server can use the initialized notification for example to dynamically register capabilities.\n// The initialized notification may only be sent once.\nfunc (s *server) Initialized(ctx context.Context, params *InitializedParams) (err error) {\n\ts.logger.Debug(\"notify \" + MethodInitialized)\n\tdefer s.logger.Debug(\"end \"+MethodInitialized, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodInitialized, params)\n}\n\n// Shutdown sents the request from the client to the server.\n//\n// It asks the server to shut down, 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//\n// Clients must not sent any notifications other than `exit` or requests to a server to which they have sent a shutdown requests.\n// If a server receives requests after a shutdown request those requests should be errored with `InvalidRequest`.\nfunc (s *server) Shutdown(ctx context.Context) (err error) {\n\ts.logger.Debug(\"call \" + MethodShutdown)\n\tdefer s.logger.Debug(\"end \"+MethodShutdown, slog.Any(\"error\", err))\n\n\treturn Call(ctx, s.Conn, MethodShutdown, nil, nil)\n}\n\n// Exit a notification to ask the server to exit its process.\n//\n// The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1.\nfunc (s *server) Exit(ctx context.Context) (err error) {\n\ts.logger.Debug(\"notify \" + MethodExit)\n\tdefer s.logger.Debug(\"end \"+MethodExit, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodExit, nil)\n}\n\n// LogTrace a notification to log the trace of the server’s execution.\n//\n// The amount and content of these notifications depends on the current trace configuration.\n//\n// If trace is \"off\", the server should not send any logTrace notification. If trace is \"message\",\n// the server should not add the \"verbose\" field in the LogTraceParams.\n//\n// @since 3.16.0.\nfunc (s *server) LogTrace(ctx context.Context, params *LogTraceParams) (err error) {\n\ts.logger.Debug(\"notify \" + MethodLogTrace)\n\tdefer s.logger.Debug(\"end \"+MethodLogTrace, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodLogTrace, params)\n}\n\n// SetTrace a notification that should be used by the client to modify the trace setting of the server.\n//\n// @since 3.16.0.\nfunc (s *server) SetTrace(ctx context.Context, params *SetTraceParams) (err error) {\n\ts.logger.Debug(\"notify \" + MethodSetTrace)\n\tdefer s.logger.Debug(\"end \"+MethodSetTrace, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodSetTrace, params)\n}\n\n// WorkDoneProgressCancel is the sends notification from the client to the server to cancel a progress initiated on the\n// server side using the \"window/workDoneProgress/create\".\nfunc (s *server) WorkDoneProgressCancel(ctx context.Context, params *WorkDoneProgressCancelParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodWorkDoneProgressCancel)\n\tdefer s.logger.Debug(\"end \"+MethodWorkDoneProgressCancel, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodWorkDoneProgressCancel, params)\n}\n\n// CodeAction sends the request is from the client to the server to compute commands for a given text document and range.\n//\n// These commands are typically code fixes to either fix problems or to beautify/refactor code. The result of a `textDocument/codeAction`\n// request is an array of `Command` literals which are typically presented in the user interface.\n//\n// To ensure that a server is useful in many clients the commands specified in a code actions should be handled by the\n// server and not by the client (see `workspace/executeCommand` and `ServerCapabilities.executeCommandProvider`).\n// If the client supports providing edits with a code action then the mode should be used.\nfunc (s *server) CodeAction(ctx context.Context, params *CodeActionParams) (result []CodeAction, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentCodeAction)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentCodeAction, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentCodeAction, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// CodeLens sends the request from the client to the server to compute code lenses for a given text document.\nfunc (s *server) CodeLens(ctx context.Context, params *CodeLensParams) (result []CodeLens, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentCodeLens)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentCodeLens, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentCodeLens, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// CodeLensResolve sends the request from the client to the server to resolve the command for a given code lens item.\nfunc (s *server) CodeLensResolve(ctx context.Context, params *CodeLens) (_ *CodeLens, err error) {\n\ts.logger.Debug(\"call \" + MethodCodeLensResolve)\n\tdefer s.logger.Debug(\"end \"+MethodCodeLensResolve, slog.Any(\"error\", err))\n\n\tvar result *CodeLens\n\tif err := Call(ctx, s.Conn, MethodCodeLensResolve, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// ColorPresentation sends the request from the client to the server to obtain a list of presentations for a color value at a given location.\n//\n// # Clients can use the result to\n//\n// - modify a color reference.\n// - show in a color picker and let users pick one of the presentations.\nfunc (s *server) ColorPresentation(ctx context.Context, params *ColorPresentationParams) (result []ColorPresentation, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentColorPresentation)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentColorPresentation, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentColorPresentation, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Completion sends the request from the client to the server to compute completion items at a given cursor position.\n//\n// Completion items are presented in the IntelliSense user interface.\n// If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request (‘completionItem/resolve’).\n//\n// This request is sent when a completion item is selected in the user interface.\n// A typical use case is for example: the ‘textDocument/completion’ request doesn’t fill in the documentation property\n// for returned completion items since it is expensive to compute. When the item is selected in the user interface then\n// a ‘completionItem/resolve’ request is sent with the selected completion item as a parameter.\n//\n// The returned completion item should have the documentation property filled in. The request can delay the computation of\n// the `detail` and `documentation` properties. However, properties that are needed for the initial sorting and filtering,\n// like `sortText`, `filterText`, `insertText`, and `textEdit` must be provided in the `textDocument/completion` response and must not be changed during resolve.\nfunc (s *server) Completion(ctx context.Context, params *CompletionParams) (_ *CompletionList, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentCompletion)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentCompletion, slog.Any(\"error\", err))\n\n\tvar result *CompletionList\n\tif err := Call(ctx, s.Conn, MethodTextDocumentCompletion, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// CompletionResolve sends the request from the client to the server to resolve additional information for a given completion item.\nfunc (s *server) CompletionResolve(ctx context.Context, params *CompletionItem) (_ *CompletionItem, err error) {\n\ts.logger.Debug(\"call \" + MethodCompletionItemResolve)\n\tdefer s.logger.Debug(\"end \"+MethodCompletionItemResolve, slog.Any(\"error\", err))\n\n\tvar result *CompletionItem\n\tif err := Call(ctx, s.Conn, MethodCompletionItemResolve, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Declaration sends the request from the client to the server to resolve the declaration location of a symbol at a given text document position.\n//\n// The result type LocationLink[] got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.textDocument.declaration.linkSupport`.\n//\n// @since 3.14.0.\nfunc (s *server) Declaration(ctx context.Context, params *DeclarationParams) (result []Location, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDeclaration)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDeclaration, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentDeclaration, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Definition sends the request from the client to the server to resolve the definition location of a symbol at a given text document position.\n//\n// The result type `[]LocationLink` got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.textDocument.definition.linkSupport`.\n//\n// @since 3.14.0.\nfunc (s *server) Definition(ctx context.Context, params *DefinitionParams) (result []Location, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDefinition)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDefinition, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentDefinition, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DidChange sends the notification from the client to the server to signal changes to a text document.\n//\n// In 2.0 the shape of the params has changed to include proper version numbers and language ids.\nfunc (s *server) DidChange(ctx context.Context, params *DidChangeTextDocumentParams) (err error) {\n\ts.logger.Debug(\"notify \" + MethodTextDocumentDidChange)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDidChange, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodTextDocumentDidChange, params)\n}\n\n// DidChangeConfiguration sends the notification from the client to the server to signal the change of configuration settings.\nfunc (s *server) DidChangeConfiguration(ctx context.Context, params *DidChangeConfigurationParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodWorkspaceDidChangeConfiguration)\n\tdefer s.logger.Debug(\"end \"+MethodWorkspaceDidChangeConfiguration, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodWorkspaceDidChangeConfiguration, params)\n}\n\n// DidChangeWatchedFiles sends the notification from the client to the server when the client detects changes to files watched by the language client.\n//\n// It is recommended that servers register for these file events using the registration mechanism.\n// In former implementations clients pushed file events without the server actively asking for it.\nfunc (s *server) DidChangeWatchedFiles(ctx context.Context, params *DidChangeWatchedFilesParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodWorkspaceDidChangeWatchedFiles)\n\tdefer s.logger.Debug(\"end \"+MethodWorkspaceDidChangeWatchedFiles, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodWorkspaceDidChangeWatchedFiles, params)\n}\n\n// DidChangeWorkspaceFolders sents the notification from the client to the server to inform the server about workspace folder configuration changes.\n//\n// The notification is sent by default if both ServerCapabilities/workspace/workspaceFolders and ClientCapabilities/workspace/workspaceFolders are true;\n// or if the server has registered itself to receive this notification.\n// To register for the workspace/didChangeWorkspaceFolders send a client/registerCapability request from the server to the client.\n//\n// The registration parameter must have a registrations item of the following form, where id is a unique id used to unregister the capability (the example uses a UUID).\nfunc (s *server) DidChangeWorkspaceFolders(ctx context.Context, params *DidChangeWorkspaceFoldersParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodWorkspaceDidChangeWorkspaceFolders)\n\tdefer s.logger.Debug(\"end \"+MethodWorkspaceDidChangeWorkspaceFolders, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodWorkspaceDidChangeWorkspaceFolders, params)\n}\n\n// DidClose sends the notification from the client to the server when the document got closed in the client.\n//\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 the truth now exists on disk).\n// As with the open notification the close notification is about managing the document’s content.\n// Receiving a close notification doesn’t mean that the document was open in an editor before.\n//\n// A close notification requires a previous open notification to be sent.\n// Note that a server’s ability to fulfill requests is independent of whether a text document is open or closed.\nfunc (s *server) DidClose(ctx context.Context, params *DidCloseTextDocumentParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDidClose)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDidClose, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodTextDocumentDidClose, params)\n}\n\n// DidOpen sends the open notification from the client to the server to signal newly opened text documents.\n//\n// The document’s truth is now managed by the client and the server must not try to read the document’s truth using the document’s Uri.\n// Open in this sense means it is managed by the client. It doesn’t necessarily mean that its content is presented in an editor.\n//\n// An open notification must not be sent more than once without a corresponding close notification send before.\n// This means open and close notification must be balanced and the max open count for a particular textDocument is one.\n// Note that a server’s ability to fulfill requests is independent of whether a text document is open or closed.\nfunc (s *server) DidOpen(ctx context.Context, params *DidOpenTextDocumentParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDidOpen)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDidOpen, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodTextDocumentDidOpen, params)\n}\n\n// DidSave sends the notification from the client to the server when the document was saved in the client.\nfunc (s *server) DidSave(ctx context.Context, params *DidSaveTextDocumentParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDidSave)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDidSave, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodTextDocumentDidSave, params)\n}\n\n// DocumentColor sends the request from the client to the server to list all color references found in a given text document.\n//\n// Along with the range, a color value in RGB is returned.\n//\n// Clients can use the result to decorate color references in an editor.\n// For example:\n//\n// - Color boxes showing the actual color next to the reference\n// - Show a color picker when a color reference is edited.\nfunc (s *server) DocumentColor(ctx context.Context, params *DocumentColorParams) (result []ColorInformation, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDocumentColor)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDocumentColor, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentDocumentColor, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DocumentHighlight sends the request is from the client to the server to resolve a document highlights for a given text document position.\n//\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 the first one is allowed to be more fuzzy.\n//\n// Symbol matches usually have a `DocumentHighlightKind` of `Read` or `Write` whereas fuzzy or textual matches use `Text` as the kind.\nfunc (s *server) DocumentHighlight(ctx context.Context, params *DocumentHighlightParams) (result []DocumentHighlight, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDocumentHighlight)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDocumentHighlight, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentDocumentHighlight, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DocumentLink sends the request from the client to the server to request the location of links in a document.\nfunc (s *server) DocumentLink(ctx context.Context, params *DocumentLinkParams) (result []DocumentLink, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDocumentLink)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDocumentLink, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentDocumentLink, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DocumentLinkResolve sends the request from the client to the server to resolve the target of a given document link.\nfunc (s *server) DocumentLinkResolve(ctx context.Context, params *DocumentLink) (_ *DocumentLink, err error) {\n\ts.logger.Debug(\"call \" + MethodDocumentLinkResolve)\n\tdefer s.logger.Debug(\"end \"+MethodDocumentLinkResolve, slog.Any(\"error\", err))\n\n\tvar result *DocumentLink\n\tif err := Call(ctx, s.Conn, MethodDocumentLinkResolve, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DocumentSymbol sends the request from the client to the server to return a flat list of all symbols found in a given text document.\n//\n// Neither the symbol’s location range nor the symbol’s container name should be used to infer a hierarchy.\nfunc (s *server) DocumentSymbol(ctx context.Context, params *DocumentSymbolParams) (result []SymbolInformationOrDocumentSymbol, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentDocumentSymbol)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentDocumentSymbol, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentDocumentSymbol, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// ExecuteCommand sends the request from the client to the server to trigger command execution on the server.\n//\n// In most cases the server creates a `WorkspaceEdit` structure and applies the changes to the workspace using the\n// request `workspace/applyEdit` which is sent from the server to the client.\nfunc (s *server) ExecuteCommand(ctx context.Context, params *ExecuteCommandParams) (result any, err error) {\n\ts.logger.Debug(\"call \" + MethodWorkspaceExecuteCommand)\n\tdefer s.logger.Debug(\"end \"+MethodWorkspaceExecuteCommand, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodWorkspaceExecuteCommand, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// FoldingRanges sends the request from the client to the server to return all folding ranges found in a given text document.\n//\n// @since version 3.10.0.\nfunc (s *server) FoldingRanges(ctx context.Context, params *FoldingRangeParams) (result []FoldingRange, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentFoldingRange)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentFoldingRange, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentFoldingRange, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Formatting sends the request from the client to the server to format a whole document.\nfunc (s *server) Formatting(ctx context.Context, params *DocumentFormattingParams) (result []TextEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentFormatting)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentFormatting, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentFormatting, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Hover sends the request is from the client to the server to request hover information at a given text document position.\nfunc (s *server) Hover(ctx context.Context, params *HoverParams) (_ *Hover, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentHover)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentHover, slog.Any(\"error\", err))\n\n\tvar result *Hover\n\tif err := Call(ctx, s.Conn, MethodTextDocumentHover, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Implementation sends the request from the client to the server to resolve the implementation location of a symbol at a given text document position.\n//\n// The result type `[]LocationLink` got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.implementation.typeDefinition.linkSupport`.\nfunc (s *server) Implementation(ctx context.Context, params *ImplementationParams) (result []Location, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentImplementation)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentImplementation, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentImplementation, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// OnTypeFormatting sends the request from the client to the server to format parts of the document during typing.\nfunc (s *server) OnTypeFormatting(ctx context.Context, params *DocumentOnTypeFormattingParams) (result []TextEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentOnTypeFormatting)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentOnTypeFormatting, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentOnTypeFormatting, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// PrepareRename sends the request from the client to the server to setup and test the validity of a rename operation at a given location.\n//\n// @since version 3.12.0.\nfunc (s *server) PrepareRename(ctx context.Context, params *PrepareRenameParams) (result *Range, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentPrepareRename)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentPrepareRename, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentPrepareRename, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// RangeFormatting sends the request from the client to the server to format a given range in a document.\nfunc (s *server) RangeFormatting(ctx context.Context, params *DocumentRangeFormattingParams) (result []TextEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentRangeFormatting)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentRangeFormatting, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentRangeFormatting, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// References sends the request from the client to the server to resolve project-wide references for the symbol denoted by the given text document position.\nfunc (s *server) References(ctx context.Context, params *ReferenceParams) (result []Location, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentReferences)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentReferences, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentReferences, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Rename sends the request from the client to the server to perform a workspace-wide rename of a symbol.\nfunc (s *server) Rename(ctx context.Context, params *RenameParams) (result *WorkspaceEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentRename)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentRename, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentRename, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// SignatureHelp sends the request from the client to the server to request signature information at a given cursor position.\nfunc (s *server) SignatureHelp(ctx context.Context, params *SignatureHelpParams) (_ *SignatureHelp, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentSignatureHelp)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentSignatureHelp, slog.Any(\"error\", err))\n\n\tvar result *SignatureHelp\n\tif err := Call(ctx, s.Conn, MethodTextDocumentSignatureHelp, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Symbols sends the request from the client to the server to list project-wide symbols matching the query string.\nfunc (s *server) Symbols(ctx context.Context, params *WorkspaceSymbolParams) (result []SymbolInformation, err error) {\n\ts.logger.Debug(\"call \" + MethodWorkspaceSymbol)\n\tdefer s.logger.Debug(\"end \"+MethodWorkspaceSymbol, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodWorkspaceSymbol, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// TypeDefinition sends the request from the client to the server to resolve the type definition location of a symbol at a given text document position.\n//\n// The result type `[]LocationLink` got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.textDocument.typeDefinition.linkSupport`.\n//\n// @since version 3.6.0.\nfunc (s *server) TypeDefinition(ctx context.Context, params *TypeDefinitionParams) (result []Location, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentTypeDefinition)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentTypeDefinition, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentTypeDefinition, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// WillSave sends the notification from the client to the server before the document is actually saved.\nfunc (s *server) WillSave(ctx context.Context, params *WillSaveTextDocumentParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentWillSave)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentWillSave, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodTextDocumentWillSave, params)\n}\n\n// WillSaveWaitUntil sends the request from the client to the server before the document is actually saved.\n//\n// The request can return an array of TextEdits which will be applied to the text document before it is saved.\n// Please note that clients might drop results if computing the text edits took too long or if a server constantly fails on this request.\n// This is done to keep the save fast and reliable.\nfunc (s *server) WillSaveWaitUntil(ctx context.Context, params *WillSaveTextDocumentParams) (result []TextEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentWillSaveWaitUntil)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentWillSaveWaitUntil, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentWillSaveWaitUntil, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// ShowDocument sends the request from a server to a client to ask the client to display a particular document in the user interface.\n//\n// @since 3.16.0.\nfunc (s *server) ShowDocument(ctx context.Context, params *ShowDocumentParams) (result *ShowDocumentResult, err error) {\n\ts.logger.Debug(\"call \" + MethodShowDocument)\n\tdefer s.logger.Debug(\"end \"+MethodShowDocument, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodShowDocument, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// WillCreateFiles sends 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.\n//\n// The request can return a WorkspaceEdit which will be applied to workspace before the files are created.\n//\n// 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.\n//\n// @since 3.16.0.\nfunc (s *server) WillCreateFiles(ctx context.Context, params *CreateFilesParams) (result *WorkspaceEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodWillCreateFiles)\n\tdefer s.logger.Debug(\"end \"+MethodWillCreateFiles, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodWillCreateFiles, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DidCreateFiles sends the did create files notification is sent from the client to the server when files were created from within the client.\n//\n// @since 3.16.0.\nfunc (s *server) DidCreateFiles(ctx context.Context, params *CreateFilesParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodDidCreateFiles)\n\tdefer s.logger.Debug(\"end \"+MethodDidCreateFiles, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodDidCreateFiles, params)\n}\n\n// WillRenameFiles sends 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.\n//\n// The request can return a WorkspaceEdit which will be applied to workspace before the files are renamed.\n//\n// 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.\n//\n// @since 3.16.0.\nfunc (s *server) WillRenameFiles(ctx context.Context, params *RenameFilesParams) (result *WorkspaceEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodWillRenameFiles)\n\tdefer s.logger.Debug(\"end \"+MethodWillRenameFiles, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodWillRenameFiles, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DidRenameFiles sends the did rename files notification is sent from the client to the server when files were renamed from within the client.\n//\n// @since 3.16.0.\nfunc (s *server) DidRenameFiles(ctx context.Context, params *RenameFilesParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodDidRenameFiles)\n\tdefer s.logger.Debug(\"end \"+MethodDidRenameFiles, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodDidRenameFiles, params)\n}\n\n// WillDeleteFiles sends 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.\n//\n// The request can return a WorkspaceEdit which will be applied to workspace before the files are deleted.\n//\n// 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.\n//\n// @since 3.16.0.\nfunc (s *server) WillDeleteFiles(ctx context.Context, params *DeleteFilesParams) (result *WorkspaceEdit, err error) {\n\ts.logger.Debug(\"call \" + MethodWillDeleteFiles)\n\tdefer s.logger.Debug(\"end \"+MethodWillDeleteFiles, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodWillDeleteFiles, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// DidDeleteFiles sends the did delete files notification is sent from the client to the server when files were deleted from within the client.\n//\n// @since 3.16.0.\nfunc (s *server) DidDeleteFiles(ctx context.Context, params *DeleteFilesParams) (err error) {\n\ts.logger.Debug(\"call \" + MethodDidDeleteFiles)\n\tdefer s.logger.Debug(\"end \"+MethodDidDeleteFiles, slog.Any(\"error\", err))\n\n\treturn s.Notify(ctx, MethodDidDeleteFiles, params)\n}\n\n// CodeLensRefresh sent from the server to the client.\n//\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//\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.\n//\n// @since 3.16.0.\nfunc (s *server) CodeLensRefresh(ctx context.Context) (err error) {\n\ts.logger.Debug(\"call \" + MethodCodeLensRefresh)\n\tdefer s.logger.Debug(\"end \"+MethodCodeLensRefresh, slog.Any(\"error\", err))\n\n\treturn Call(ctx, s.Conn, MethodCodeLensRefresh, nil, nil)\n}\n\n// PrepareCallHierarchy sent from the client to the server to return a call hierarchy for the language element of given text document positions.\n//\n// The call hierarchy requests are executed in two steps:\n//  1. first a call hierarchy item is resolved for the given text document position\n//  2. for a call hierarchy item the incoming or outgoing call hierarchy items are resolved.\n//\n// @since 3.16.0.\nfunc (s *server) PrepareCallHierarchy(ctx context.Context, params *CallHierarchyPrepareParams) (result []CallHierarchyItem, err error) {\n\ts.logger.Debug(\"call \" + MethodTextDocumentPrepareCallHierarchy)\n\tdefer s.logger.Debug(\"end \"+MethodTextDocumentPrepareCallHierarchy, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodTextDocumentPrepareCallHierarchy, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// IncomingCalls is the request is sent from the client to the server to resolve incoming calls for a given call hierarchy item.\n//\n// The request doesn’t define its own client and server capabilities. It is only issued if a server registers for the \"textDocument/prepareCallHierarchy\" request.\n//\n// @since 3.16.0.\nfunc (s *server) IncomingCalls(ctx context.Context, params *CallHierarchyIncomingCallsParams) (result []CallHierarchyIncomingCall, err error) {\n\ts.logger.Debug(\"call \" + MethodCallHierarchyIncomingCalls)\n\tdefer s.logger.Debug(\"end \"+MethodCallHierarchyIncomingCalls, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodCallHierarchyIncomingCalls, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// OutgoingCalls is the request is sent from the client to the server to resolve outgoing calls for a given call hierarchy item.\n//\n// The request doesn’t define its own client and server capabilities. It is only issued if a server registers for the \"textDocument/prepareCallHierarchy\" request.\n//\n// @since 3.16.0.\nfunc (s *server) OutgoingCalls(ctx context.Context, params *CallHierarchyOutgoingCallsParams) (result []CallHierarchyOutgoingCall, err error) {\n\ts.logger.Debug(\"call \" + MethodCallHierarchyOutgoingCalls)\n\tdefer s.logger.Debug(\"end \"+MethodCallHierarchyOutgoingCalls, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodCallHierarchyOutgoingCalls, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// SemanticTokensFull is the request is sent from the client to the server to resolve semantic tokens for a given file.\n//\n// Semantic tokens are used to add additional color information to a file that depends on language specific symbol information.\n//\n// A semantic token request usually produces a large result. The protocol therefore supports encoding tokens with numbers.\n//\n// @since 3.16.0.\nfunc (s *server) SemanticTokensFull(ctx context.Context, params *SemanticTokensParams) (result *SemanticTokens, err error) {\n\ts.logger.Debug(\"call \" + MethodSemanticTokensFull)\n\tdefer s.logger.Debug(\"end \"+MethodSemanticTokensFull, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodSemanticTokensFull, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// SemanticTokensFullDelta is the request is sent from the client to the server to resolve semantic token delta for a given file.\n//\n// Semantic tokens are used to add additional color information to a file that depends on language specific symbol information.\n//\n// A semantic token request usually produces a large result. The protocol therefore supports encoding tokens with numbers.\n//\n// @since 3.16.0.\nfunc (s *server) SemanticTokensFullDelta(ctx context.Context, params *SemanticTokensDeltaParams) (result any, err error) {\n\ts.logger.Debug(\"call \" + MethodSemanticTokensFullDelta)\n\tdefer s.logger.Debug(\"end \"+MethodSemanticTokensFullDelta, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodSemanticTokensFullDelta, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// SemanticTokensRange is the request is sent from the client to the server to resolve semantic token delta for a given file.\n//\n// When a user opens a file it can be beneficial to only compute the semantic tokens for the visible range (faster rendering of the tokens in the user interface).\n// If a server can compute these tokens faster than for the whole file it can provide a handler for the \"textDocument/semanticTokens/range\" request to handle this case special.\n//\n// Please note that if a client also announces that it will send the \"textDocument/semanticTokens/range\" server should implement this request as well to allow for flicker free scrolling and semantic coloring of a minimap.\n//\n// @since 3.16.0.\nfunc (s *server) SemanticTokensRange(ctx context.Context, params *SemanticTokensRangeParams) (result *SemanticTokens, err error) {\n\ts.logger.Debug(\"call \" + MethodSemanticTokensRange)\n\tdefer s.logger.Debug(\"end \"+MethodSemanticTokensRange, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodSemanticTokensRange, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// SemanticTokensRefresh is sent from the server to the client. Servers can use it to ask clients to refresh the editors for which this server provides semantic tokens.\n//\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//\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.\n//\n// @since 3.16.0.\nfunc (s *server) SemanticTokensRefresh(ctx context.Context) (err error) {\n\ts.logger.Debug(\"call \" + MethodSemanticTokensRefresh)\n\tdefer s.logger.Debug(\"end \"+MethodSemanticTokensRefresh, slog.Any(\"error\", err))\n\n\treturn Call(ctx, s.Conn, MethodSemanticTokensRefresh, nil, nil)\n}\n\n// LinkedEditingRange is the linked editing request is sent from the client to the server to return for a given position in a document the range of the symbol at the position and all ranges that have the same content.\n//\n// Optionally a word pattern can be returned to describe valid contents.\n//\n// A rename to one of the ranges can be applied to all other ranges if the new content is valid. If no result-specific word pattern is provided, the word pattern from the client’s language configuration is used.\n//\n// @since 3.16.0.\nfunc (s *server) LinkedEditingRange(ctx context.Context, params *LinkedEditingRangeParams) (result *LinkedEditingRanges, err error) {\n\ts.logger.Debug(\"call \" + MethodLinkedEditingRange)\n\tdefer s.logger.Debug(\"end \"+MethodLinkedEditingRange, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodLinkedEditingRange, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Moniker is the request is sent from the client to the server to get the symbol monikers for a given text document position.\n//\n// An array of Moniker types is returned as response to indicate possible monikers at the given location.\n//\n// If no monikers can be calculated, an empty array or null should be returned.\n//\n// @since 3.16.0.\nfunc (s *server) Moniker(ctx context.Context, params *MonikerParams) (result []Moniker, err error) {\n\ts.logger.Debug(\"call \" + MethodMoniker)\n\tdefer s.logger.Debug(\"end \"+MethodMoniker, slog.Any(\"error\", err))\n\n\tif err := Call(ctx, s.Conn, MethodMoniker, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\n// Request sends a request from the client to the server that non-compliant with the Language Server Protocol specifications.\nfunc (s *server) Request(ctx context.Context, method string, params any) (any, error) {\n\ts.logger.Debug(\"call \" + method)\n\tdefer s.logger.Debug(\"end \" + method)\n\n\tvar result any\n\tif err := Call(ctx, s.Conn, method, params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "lsp/protocol/text.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"strconv\"\n)\n\n// DidOpenTextDocumentParams params of DidOpenTextDocument notification.\ntype DidOpenTextDocumentParams struct {\n\t// TextDocument is the document that was opened.\n\tTextDocument TextDocumentItem `json:\"textDocument\"`\n}\n\n// DidChangeTextDocumentParams params of DidChangeTextDocument notification.\ntype DidChangeTextDocumentParams struct {\n\t// TextDocument is the document that did change. The version number points\n\t// to the version after all provided content changes have\n\t// been applied.\n\tTextDocument VersionedTextDocumentIdentifier `json:\"textDocument\"`\n\n\t// ContentChanges is the actual content changes. The content changes describe single state changes\n\t// to the document. So if there are two content changes c1 and c2 for a document\n\t// in state S then c1 move the document to S' and c2 to S''.\n\tContentChanges []TextDocumentContentChangeEvent `json:\"contentChanges\"` // []TextDocumentContentChangeEvent | text\n}\n\n// TextDocumentSaveReason represents reasons why a text document is saved.\ntype TextDocumentSaveReason float64\n\nconst (\n\t// TextDocumentSaveReasonManual is the manually triggered, e.g. by the user pressing save, by starting debugging,\n\t// or by an API call.\n\tTextDocumentSaveReasonManual TextDocumentSaveReason = 1\n\n\t// TextDocumentSaveReasonAfterDelay is the automatic after a delay.\n\tTextDocumentSaveReasonAfterDelay TextDocumentSaveReason = 2\n\n\t// TextDocumentSaveReasonFocusOut when the editor lost focus.\n\tTextDocumentSaveReasonFocusOut TextDocumentSaveReason = 3\n)\n\n// String implements fmt.Stringer.\nfunc (t TextDocumentSaveReason) String() string {\n\tswitch t {\n\tcase TextDocumentSaveReasonManual:\n\t\treturn \"Manual\"\n\tcase TextDocumentSaveReasonAfterDelay:\n\t\treturn \"AfterDelay\"\n\tcase TextDocumentSaveReasonFocusOut:\n\t\treturn \"FocusOut\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(t), 'f', -10, 64)\n\t}\n}\n\n// TextDocumentChangeRegistrationOptions describe options to be used when registering for text document change events.\ntype TextDocumentChangeRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// SyncKind how documents are synced to the server. See TextDocumentSyncKind.Full\n\t// and TextDocumentSyncKind.Incremental.\n\tSyncKind TextDocumentSyncKind `json:\"syncKind\"`\n}\n\n// WillSaveTextDocumentParams is the parameters send in a will save text document notification.\ntype WillSaveTextDocumentParams struct {\n\t// TextDocument is the document that will be saved.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n\n\t// Reason is the 'TextDocumentSaveReason'.\n\tReason TextDocumentSaveReason `json:\"reason,omitempty\"`\n}\n\n// DidSaveTextDocumentParams params of DidSaveTextDocument notification.\ntype DidSaveTextDocumentParams struct {\n\t// Text optional the content when saved. Depends on the includeText value\n\t// when the save notification was requested.\n\tText string `json:\"text,omitempty\"`\n\n\t// TextDocument is the document that was saved.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n\n// TextDocumentContentChangeEvent 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.\ntype TextDocumentContentChangeEvent struct {\n\t// Range is the range of the document that changed.\n\tRange *Range `json:\"range,omitempty\"`\n\n\t// RangeLength is the length of the range that got replaced.\n\tRangeLength uint32 `json:\"rangeLength,omitempty\"`\n\n\t// Text is the new text of the document.\n\tText string `json:\"text\"`\n}\n\n// TextDocumentSaveRegistrationOptions TextDocumentSave Registration options.\ntype TextDocumentSaveRegistrationOptions struct {\n\tTextDocumentRegistrationOptions\n\n\t// IncludeText is the client is supposed to include the content on save.\n\tIncludeText bool `json:\"includeText,omitempty\"`\n}\n\n// DidCloseTextDocumentParams params of DidCloseTextDocument notification.\ntype DidCloseTextDocumentParams struct {\n\t// TextDocument the document that was closed.\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\"`\n}\n"
  },
  {
    "path": "lsp/protocol/text_test.go",
    "content": "// SPDX-FileCopyrightText: 2020 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\nfunc TestDidOpenTextDocumentParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\",\"languageId\":\"go\",\"version\":10,\"text\":\"Go Language\"}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\",\"languageId\":\"cpp\",\"version\":10,\"text\":\"C++ Language\"}}`\n\t)\n\twantType := DidOpenTextDocumentParams{\n\t\tTextDocument: TextDocumentItem{\n\t\t\tURI:        uri.File(\"/path/to/basic.go\"),\n\t\t\tLanguageID: GoLanguage,\n\t\t\tVersion:    int32(10),\n\t\t\tText:       \"Go Language\",\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidOpenTextDocumentParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidOpenTextDocumentParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidOpenTextDocumentParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDidChangeTextDocumentParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\",\"version\":10},\"contentChanges\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":25,\"character\":3}},\"rangeLength\":2,\"text\":\"testText\"}]}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\",\"version\":10},\"contentChanges\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":4}},\"rangeLength\":3,\"text\":\"invalidText\"}]}`\n\t)\n\twantType := DidChangeTextDocumentParams{\n\t\tTextDocument: VersionedTextDocumentIdentifier{\n\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t\t},\n\t\t\tVersion: int32(10),\n\t\t},\n\t\tContentChanges: []TextDocumentContentChangeEvent{\n\t\t\t{\n\t\t\t\tRange: &Range{\n\t\t\t\t\tStart: Position{\n\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t},\n\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRangeLength: 2,\n\t\t\t\tText:        \"testText\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidChangeTextDocumentParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidChangeTextDocumentParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidChangeTextDocumentParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentSaveReason_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    TextDocumentSaveReason\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Manual\",\n\t\t\tk:    TextDocumentSaveReasonManual,\n\t\t\twant: \"Manual\",\n\t\t},\n\t\t{\n\t\t\tname: \"AfterDelay\",\n\t\t\tk:    TextDocumentSaveReasonAfterDelay,\n\t\t\twant: \"AfterDelay\",\n\t\t},\n\t\t{\n\t\t\tname: \"FocusOut\",\n\t\t\tk:    TextDocumentSaveReasonFocusOut,\n\t\t\twant: \"FocusOut\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    TextDocumentSaveReason(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"TextDocumentSaveReason.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTextDocumentContentChangeEvent(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant           = `{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":25,\"character\":3}},\"rangeLength\":2,\"text\":\"testText\"}`\n\t\twantInvalid    = `{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":4}},\"rangeLength\":3,\"text\":\"invalidText\"}`\n\t\twantReplaceAll = `{\"text\":\"replace all\"}`\n\t)\n\twantType := TextDocumentContentChangeEvent{\n\t\tRange: &Range{\n\t\t\tStart: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 1,\n\t\t\t},\n\t\t\tEnd: Position{\n\t\t\t\tLine:      25,\n\t\t\t\tCharacter: 3,\n\t\t\t},\n\t\t},\n\t\tRangeLength: 2,\n\t\tText:        \"testText\",\n\t}\n\twantReplaceAllType := TextDocumentContentChangeEvent{\n\t\tText: \"replace all\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentContentChangeEvent\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ReplaceAll\",\n\t\t\t\tfield:          wantReplaceAllType,\n\t\t\t\twant:           wantReplaceAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentContentChangeEvent\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentContentChangeEvent\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentChangeRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"}],\"syncKind\":2}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"syncKind\":1}`\n\t)\n\twantType := TextDocumentChangeRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tSyncKind: 2,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentChangeRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentChangeRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentChangeRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWillSaveTextDocumentParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"},\"reason\":3}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"},\"reason\":1}`\n\t)\n\twantType := WillSaveTextDocumentParams{\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t\tReason: TextDocumentSaveReasonFocusOut,\n\t}\n\twantTypeNilAll := WillSaveTextDocumentParams{\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WillSaveTextDocumentParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WillSaveTextDocumentParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WillSaveTextDocumentParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDidSaveTextDocumentParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"text\":\"testText\",\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantNilAll  = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"text\":\"invalidText\",\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"}}`\n\t)\n\twantType := DidSaveTextDocumentParams{\n\t\tText: \"testText\",\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\twantTypeNilAll := DidSaveTextDocumentParams{\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidSaveTextDocumentParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidSaveTextDocumentParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidSaveTextDocumentParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestTextDocumentSaveRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"}],\"includeText\":true}`\n\t\twantNilAll  = `{\"documentSelector\":[{\"language\":\"go\",\"scheme\":\"file\",\"pattern\":\"*.go\"}]}`\n\t\twantInvalid = `{\"documentSelector\":[{\"language\":\"typescript\",\"scheme\":\"file\",\"pattern\":\"*.{ts,js}\"}],\"includeText\":false}`\n\t)\n\twantType := TextDocumentSaveRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tIncludeText: true,\n\t}\n\twantTypeNilAll := TextDocumentSaveRegistrationOptions{\n\t\tTextDocumentRegistrationOptions: TextDocumentRegistrationOptions{\n\t\t\tDocumentSelector: DocumentSelector{\n\t\t\t\t{\n\t\t\t\t\tLanguage: \"go\",\n\t\t\t\t\tScheme:   \"file\",\n\t\t\t\t\tPattern:  \"*.go\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          TextDocumentSaveRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             TextDocumentSaveRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got TextDocumentSaveRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDidCloseTextDocumentParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"textDocument\":{\"uri\":\"file:///path/to/test.go\"}}`\n\t\twantInvalid = `{\"textDocument\":{\"uri\":\"file:///path/to/invalid.go\"}}`\n\t)\n\twantType := DidCloseTextDocumentParams{\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri.File(\"/path/to/test.go\"),\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidCloseTextDocumentParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidCloseTextDocumentParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidCloseTextDocumentParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/protocol/util.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// NewVersion returns the int32 pointer converted i.\nfunc NewVersion(i int32) *int32 {\n\treturn &i\n}\n"
  },
  {
    "path": "lsp/protocol/util_test.go",
    "content": "// SPDX-FileCopyrightText: 2020 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"testing\"\n)\n\nfunc TestNewVersion(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\ti    int32\n\t}{\n\t\t{\n\t\t\tname: \"Valid\",\n\t\t\ti:    5000,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\twant := NewVersion(tt.i)\n\t\t\tif got := NewVersion(tt.i); *got != *want {\n\t\t\t\tt.Errorf(\"NewVersion(%v) = %v, want %v\", tt.i, *got, *want)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "lsp/protocol/version.go",
    "content": "// SPDX-FileCopyrightText: 2018 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\n// Version is the version of the language-server-protocol specification being implemented.\nconst Version = \"3.15.3\"\n"
  },
  {
    "path": "lsp/protocol/window.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport \"strconv\"\n\n// ShowMessageParams params of ShowMessage notification.\ntype ShowMessageParams struct {\n\t// Message is the actual message.\n\tMessage string `json:\"message\"`\n\n\t// Type is the message type.\n\tType MessageType `json:\"type\"`\n}\n\n// MessageType type of ShowMessageParams type.\ntype MessageType float64\n\nconst (\n\t// MessageTypeError an error message.\n\tMessageTypeError MessageType = 1\n\t// MessageTypeWarning a warning message.\n\tMessageTypeWarning MessageType = 2\n\t// MessageTypeInfo an information message.\n\tMessageTypeInfo MessageType = 3\n\t// MessageTypeLog a log message.\n\tMessageTypeLog MessageType = 4\n)\n\n// String implements fmt.Stringer.\nfunc (m MessageType) String() string {\n\tswitch m {\n\tcase MessageTypeError:\n\t\treturn \"error\"\n\tcase MessageTypeWarning:\n\t\treturn \"warning\"\n\tcase MessageTypeInfo:\n\t\treturn \"info\"\n\tcase MessageTypeLog:\n\t\treturn \"log\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(m), 'f', -10, 64)\n\t}\n}\n\n// Enabled reports whether the level is enabled.\nfunc (m MessageType) Enabled(level MessageType) bool {\n\treturn level > 0 && m >= level\n}\n\n// messageTypeMap map of MessageTypes.\nvar messageTypeMap = map[string]MessageType{\n\t\"error\":   MessageTypeError,\n\t\"warning\": MessageTypeWarning,\n\t\"info\":    MessageTypeInfo,\n\t\"log\":     MessageTypeLog,\n}\n\n// ToMessageType converts level to the MessageType.\nfunc ToMessageType(level string) MessageType {\n\tmt, ok := messageTypeMap[level]\n\tif !ok {\n\t\treturn MessageType(0) // unknown\n\t}\n\n\treturn mt\n}\n\n// ShowMessageRequestParams params of ShowMessage request.\ntype ShowMessageRequestParams struct {\n\t// Actions is the message action items to present.\n\tActions []MessageActionItem `json:\"actions\"`\n\n\t// Message is the actual message\n\tMessage string `json:\"message\"`\n\n\t// Type is the message type. See {@link MessageType}\n\tType MessageType `json:\"type\"`\n}\n\n// MessageActionItem item of ShowMessageRequestParams action.\ntype MessageActionItem struct {\n\t// Title a short title like 'Retry', 'Open Log' etc.\n\tTitle string `json:\"title\"`\n}\n\n// LogMessageParams params of LogMessage notification.\ntype LogMessageParams struct {\n\t// Message is the actual message\n\tMessage string `json:\"message\"`\n\n\t// Type is the message type. See {@link MessageType}\n\tType MessageType `json:\"type\"`\n}\n\n// WorkDoneProgressCreateParams params of WorkDoneProgressCreate request.\n//\n// @since 3.15.0.\ntype WorkDoneProgressCreateParams struct {\n\t// Token is the token to be used to report progress.\n\tToken ProgressToken `json:\"token\"`\n}\n\n// WorkDoneProgressCreateParams params of WorkDoneProgressCancel request.\n//\n// @since 3.15.0.\ntype WorkDoneProgressCancelParams struct {\n\t// Token is the token to be used to report progress.\n\tToken ProgressToken `json:\"token\"`\n}\n"
  },
  {
    "path": "lsp/protocol/window_test.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestShowMessageParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"message\":\"error message\",\"type\":1}`\n\t\twantUnknown = `{\"message\":\"unknown message\",\"type\":0}`\n\t)\n\twantType := ShowMessageParams{\n\t\tMessage: \"error message\",\n\t\tType:    MessageTypeError,\n\t}\n\twantTypeUnkonwn := ShowMessageParams{\n\t\tMessage: \"unknown message\",\n\t\tType:    MessageType(0),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ShowMessageParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Unknown\",\n\t\t\t\tfield:          wantTypeUnkonwn,\n\t\t\t\twant:           wantUnknown,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ShowMessageParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Unknown\",\n\t\t\t\tfield:            wantUnknown,\n\t\t\t\twant:             wantTypeUnkonwn,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ShowMessageParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestShowMessageRequestParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"actions\":[{\"title\":\"Retry\"}],\"message\":\"error message\",\"type\":1}`\n\t\twantUnknown = `{\"actions\":[{\"title\":\"Retry\"}],\"message\":\"unknown message\",\"type\":0}`\n\t)\n\twantType := ShowMessageRequestParams{\n\t\tActions: []MessageActionItem{\n\t\t\t{\n\t\t\t\tTitle: \"Retry\",\n\t\t\t},\n\t\t},\n\t\tMessage: \"error message\",\n\t\tType:    MessageTypeError,\n\t}\n\twantTypeUnkonwn := ShowMessageRequestParams{\n\t\tActions: []MessageActionItem{\n\t\t\t{\n\t\t\t\tTitle: \"Retry\",\n\t\t\t},\n\t\t},\n\t\tMessage: \"unknown message\",\n\t\tType:    MessageType(0),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ShowMessageRequestParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Unknown\",\n\t\t\t\tfield:          wantTypeUnkonwn,\n\t\t\t\twant:           wantUnknown,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ShowMessageRequestParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Unknown\",\n\t\t\t\tfield:            wantUnknown,\n\t\t\t\twant:             wantTypeUnkonwn,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ShowMessageRequestParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestMessageActionItem(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"title\":\"Retry\"}`\n\t\twantOpenLog = `{\"title\":\"Open Log\"}`\n\t)\n\twantType := MessageActionItem{\n\t\tTitle: \"Retry\",\n\t}\n\twantTypeOpenLog := MessageActionItem{\n\t\tTitle: \"Open Log\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          MessageActionItem\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Unknown\",\n\t\t\t\tfield:          wantTypeOpenLog,\n\t\t\t\twant:           wantOpenLog,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             MessageActionItem\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Unknown\",\n\t\t\t\tfield:            wantOpenLog,\n\t\t\t\twant:             wantTypeOpenLog,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got MessageActionItem\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestLogMessageParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"message\":\"error message\",\"type\":1}`\n\t\twantUnknown = `{\"message\":\"unknown message\",\"type\":0}`\n\t)\n\twantType := LogMessageParams{\n\t\tMessage: \"error message\",\n\t\tType:    MessageTypeError,\n\t}\n\twantTypeUnknown := LogMessageParams{\n\t\tMessage: \"unknown message\",\n\t\tType:    MessageType(0),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          LogMessageParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Unknown\",\n\t\t\t\tfield:          wantTypeUnknown,\n\t\t\t\twant:           wantUnknown,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\tt.Parallel()\n\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             LogMessageParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Unknown\",\n\t\t\t\tfield:            wantUnknown,\n\t\t\t\twant:             wantTypeUnknown,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got LogMessageParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkDoneProgressCreateParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantToken    = int32(1569)\n\t\tinvalidToken = int32(1348)\n\t)\n\tvar (\n\t\twantString        = `{\"token\":\"` + strconv.FormatInt(int64(wantToken), 10) + `\"}`\n\t\twantInvalidString = `{\"token\":\"` + strconv.FormatInt(int64(invalidToken), 10) + `\"}`\n\t\twantNumber        = `{\"token\":` + strconv.FormatInt(int64(wantToken), 10) + `}`\n\t\twantInvalidNumber = `{\"token\":` + strconv.FormatInt(int64(invalidToken), 10) + `}`\n\t)\n\ttoken := NewProgressToken(strconv.FormatInt(int64(wantToken), 10))\n\twantTypeString := WorkDoneProgressCreateParams{\n\t\tToken: *token,\n\t}\n\tnumberToken := NewNumberProgressToken(wantToken)\n\twantTypeNumber := WorkDoneProgressCreateParams{\n\t\tToken: *numberToken,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkDoneProgressCreateParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid/String\",\n\t\t\t\tfield:          wantTypeString,\n\t\t\t\twant:           wantString,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Valid/Number\",\n\t\t\t\tfield:          wantTypeNumber,\n\t\t\t\twant:           wantNumber,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid/String\",\n\t\t\t\tfield:          wantTypeString,\n\t\t\t\twant:           wantInvalidString,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid/Number\",\n\t\t\t\tfield:          wantTypeNumber,\n\t\t\t\twant:           wantInvalidNumber,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkDoneProgressCreateParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid/String\",\n\t\t\t\tfield:            wantString,\n\t\t\t\twant:             wantTypeString,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Valid/Number\",\n\t\t\t\tfield:            wantNumber,\n\t\t\t\twant:             wantTypeNumber,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid/String\",\n\t\t\t\tfield:            wantInvalidString,\n\t\t\t\twant:             wantTypeString,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid/Number\",\n\t\t\t\tfield:            wantInvalidNumber,\n\t\t\t\twant:             wantTypeNumber,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkDoneProgressCreateParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(fmt.Sprint(got.Token), strconv.FormatInt(int64(wantToken), 10)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkDoneProgressCancelParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantToken    = int32(1569)\n\t\tinvalidToken = int32(1348)\n\t)\n\tvar (\n\t\twant        = `{\"token\":` + strconv.FormatInt(int64(wantToken), 10) + `}`\n\t\twantInvalid = `{\"token\":` + strconv.FormatInt(int64(invalidToken), 10) + `}`\n\t)\n\ttoken := NewNumberProgressToken(wantToken)\n\twantType := WorkDoneProgressCancelParams{\n\t\tToken: *token,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkDoneProgressCancelParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkDoneProgressCancelParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkDoneProgressCancelParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(fmt.Sprint(got.Token), strconv.FormatInt(int64(wantToken), 10)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestMessageType_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tm    MessageType\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Error\",\n\t\t\tm:    MessageTypeError,\n\t\t\twant: \"error\",\n\t\t},\n\t\t{\n\t\t\tname: \"Warning\",\n\t\t\tm:    MessageTypeWarning,\n\t\t\twant: \"warning\",\n\t\t},\n\t\t{\n\t\t\tname: \"Info\",\n\t\t\tm:    MessageTypeInfo,\n\t\t\twant: \"info\",\n\t\t},\n\t\t{\n\t\t\tname: \"Log\",\n\t\t\tm:    MessageTypeLog,\n\t\t\twant: \"log\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tm:    MessageType(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.m.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"MessageType.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMessageType_Enabled(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname  string\n\t\tm     MessageType\n\t\tlevel MessageType\n\t\twant  bool\n\t}{\n\t\t{\n\t\t\tname:  \"ErrorError\",\n\t\t\tm:     MessageTypeError,\n\t\t\tlevel: MessageTypeError,\n\t\t\twant:  true,\n\t\t},\n\t\t{\n\t\t\tname:  \"ErrorInfo\",\n\t\t\tm:     MessageTypeError,\n\t\t\tlevel: MessageTypeInfo,\n\t\t\twant:  false,\n\t\t},\n\t\t{\n\t\t\tname:  \"ErrorUnknown\",\n\t\t\tm:     MessageTypeError,\n\t\t\tlevel: MessageType(0),\n\t\t\twant:  false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.m.Enabled(tt.level); got != tt.want {\n\t\t\t\tt.Errorf(\"MessageType.Enabled(%v) = %v, want %v\", tt.level, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestToMessageType(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname  string\n\t\tlevel string\n\t\twant  MessageType\n\t}{\n\t\t{\n\t\t\tname:  \"Error\",\n\t\t\tlevel: \"error\",\n\t\t\twant:  MessageTypeError,\n\t\t},\n\t\t{\n\t\t\tname:  \"Warning\",\n\t\t\tlevel: \"warning\",\n\t\t\twant:  MessageTypeWarning,\n\t\t},\n\t\t{\n\t\t\tname:  \"Info\",\n\t\t\tlevel: \"info\",\n\t\t\twant:  MessageTypeInfo,\n\t\t},\n\t\t{\n\t\t\tname:  \"Log\",\n\t\t\tlevel: \"log\",\n\t\t\twant:  MessageTypeLog,\n\t\t},\n\t\t{\n\t\t\tname:  \"Unknown\",\n\t\t\tlevel: \"0\",\n\t\t\twant:  MessageType(0),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := ToMessageType(tt.level); got != tt.want {\n\t\t\t\tt.Errorf(\"ToMessageType(%v) = %v, want %v\", tt.level, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "lsp/protocol/workspace.go",
    "content": "// SPDX-FileCopyrightText: 2019 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\n// WorkspaceFolder response of Workspace folders request.\ntype WorkspaceFolder struct {\n\t// URI is the associated URI for this workspace folder.\n\tURI string `json:\"uri\"`\n\n\t// Name is the name of the workspace folder. Used to refer to this\n\t// workspace folder in the user interface.\n\tName string `json:\"name\"`\n}\n\n// DidChangeWorkspaceFoldersParams params of DidChangeWorkspaceFolders notification.\ntype DidChangeWorkspaceFoldersParams struct {\n\t// Event is the actual workspace folder change event.\n\tEvent WorkspaceFoldersChangeEvent `json:\"event\"`\n}\n\n// WorkspaceFoldersChangeEvent is the workspace folder change event.\ntype WorkspaceFoldersChangeEvent struct {\n\t// Added is the array of added workspace folders\n\tAdded []WorkspaceFolder `json:\"added\"`\n\n\t// Removed is the array of the removed workspace folders\n\tRemoved []WorkspaceFolder `json:\"removed\"`\n}\n\n// DidChangeConfigurationParams params of DidChangeConfiguration notification.\ntype DidChangeConfigurationParams struct {\n\t// Settings is the actual changed settings\n\tSettings any `json:\"settings,omitempty\"`\n}\n\n// ConfigurationParams params of Configuration request.\ntype ConfigurationParams struct {\n\tItems []ConfigurationItem `json:\"items\"`\n}\n\n// ConfigurationItem 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 the configuration store used be the client.\n// So a server might ask for a configuration cpp.formatterOptions 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 the setting scoped to the provided resource.\n// If the client for example uses EditorConfig to manage its settings the configuration should be returned for the passed resource URI. If the client can’t provide a configuration setting for a given scope then null need to be present in the returned array.\ntype ConfigurationItem struct {\n\t// ScopeURI is the scope to get the configuration section for.\n\tScopeURI uri.URI `json:\"scopeUri,omitempty\"`\n\n\t// Section is the configuration section asked for.\n\tSection string `json:\"section,omitempty\"`\n}\n\n// DidChangeWatchedFilesParams params of DidChangeWatchedFiles notification.\ntype DidChangeWatchedFilesParams struct {\n\t// Changes is the actual file events.\n\tChanges []*FileEvent `json:\"changes,omitempty\"`\n}\n\n// FileEvent an event describing a file change.\ntype FileEvent struct {\n\t// Type is the change type.\n\tType FileChangeType `json:\"type\"`\n\n\t// URI is the file's URI.\n\tURI uri.URI `json:\"uri\"`\n}\n\n// FileChangeType is the file event type.\ntype FileChangeType float64\n\nconst (\n\t// FileChangeTypeCreated is the file got created.\n\tFileChangeTypeCreated FileChangeType = 1\n\t// FileChangeTypeChanged is the file got changed.\n\tFileChangeTypeChanged FileChangeType = 2\n\t// FileChangeTypeDeleted is the file got deleted.\n\tFileChangeTypeDeleted FileChangeType = 3\n)\n\n// String implements fmt.Stringer.\nfunc (t FileChangeType) String() string {\n\tswitch t {\n\tcase FileChangeTypeCreated:\n\t\treturn \"Created\"\n\tcase FileChangeTypeChanged:\n\t\treturn \"Changed\"\n\tcase FileChangeTypeDeleted:\n\t\treturn \"Deleted\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(t), 'f', -10, 64)\n\t}\n}\n\n// DidChangeWatchedFilesRegistrationOptions describe options to be used when registering for file system change events.\ntype DidChangeWatchedFilesRegistrationOptions struct {\n\t// Watchers is the watchers to register.\n\tWatchers []FileSystemWatcher `json:\"watchers\"`\n}\n\n// FileSystemWatcher watchers of DidChangeWatchedFiles Registration options.\ntype FileSystemWatcher struct {\n\t// GlobPattern is the glob pattern to watch.\n\t//\n\t// Glob patterns can have the following syntax:\n\t// - `*` to match one or more characters in a path segment\n\t// - `?` to match on one character in a path segment\n\t// - `**` to match any number of path segments, including none\n\t// - `{}` to group conditions (e.g. `**/*.{ts,js}` matches all TypeScript and JavaScript files)\n\t// - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)\n\t// - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)\n\tGlobPattern string `json:\"globPattern\"`\n\n\t// Kind is the kind of events of interest. If omitted it defaults\n\t// to WatchKind.Create | WatchKind.Change | WatchKind.Delete\n\t// which is 7.\n\tKind WatchKind `json:\"kind,omitempty\"`\n}\n\n// WatchKind kind of FileSystemWatcher kind.\ntype WatchKind float64\n\nconst (\n\t// WatchKindCreate interested in create events.\n\tWatchKindCreate WatchKind = 1\n\n\t// WatchKindChange interested in change events.\n\tWatchKindChange WatchKind = 2\n\n\t// WatchKindDelete interested in delete events.\n\tWatchKindDelete WatchKind = 4\n)\n\n// String implements fmt.Stringer.\nfunc (k WatchKind) String() string {\n\tswitch k {\n\tcase WatchKindCreate:\n\t\treturn \"Create\"\n\tcase WatchKindChange:\n\t\treturn \"Change\"\n\tcase WatchKindDelete:\n\t\treturn \"Delete\"\n\tdefault:\n\t\treturn strconv.FormatFloat(float64(k), 'f', -10, 64)\n\t}\n}\n\n// WorkspaceSymbolParams is the parameters of a Workspace Symbol request.\ntype WorkspaceSymbolParams struct {\n\tWorkDoneProgressParams\n\tPartialResultParams\n\n\t// Query a query string to filter symbols by.\n\t//\n\t// Clients may send an empty string here to request all symbols.\n\tQuery string `json:\"query\"`\n}\n\n// ExecuteCommandParams params of Execute a command.\ntype ExecuteCommandParams struct {\n\tWorkDoneProgressParams\n\n\t// Command is the identifier of the actual command handler.\n\tCommand string `json:\"command\"`\n\n\t// Arguments that the command should be invoked with.\n\tArguments []any `json:\"arguments,omitempty\"`\n}\n\n// ExecuteCommandRegistrationOptions execute command registration options.\ntype ExecuteCommandRegistrationOptions struct {\n\t// Commands is the commands to be executed on the server\n\tCommands []string `json:\"commands\"`\n}\n\n// ApplyWorkspaceEditParams params of Applies a WorkspaceEdit.\ntype ApplyWorkspaceEditParams struct {\n\t// Label an optional label of the workspace edit. This label is\n\t// presented in the user interface for example on an undo\n\t// stack to undo the workspace edit.\n\tLabel string `json:\"label,omitempty\"`\n\n\t// Edit is the edits to apply.\n\tEdit WorkspaceEdit `json:\"edit\"`\n}\n\n// ApplyWorkspaceEditResponse response of Applies a WorkspaceEdit.\ntype ApplyWorkspaceEditResponse struct {\n\t// Applied indicates whether the edit was applied or not.\n\tApplied bool `json:\"applied\"`\n\n\t// FailureReason an optional textual description for why the edit was not applied.\n\t// This may be used by the server for diagnostic logging or to provide\n\t// a suitable error for a request that triggered the edit.\n\t//\n\t// @since 3.16.0.\n\tFailureReason string `json:\"failureReason,omitempty\"`\n\n\t// FailedChange depending on the client's failure handling strategy \"failedChange\"\n\t// might contain the index of the change that failed. This property is\n\t// only available if the client signals a \"failureHandlingStrategy\"\n\t// in its client capabilities.\n\t//\n\t// @since 3.16.0.\n\tFailedChange uint32 `json:\"failedChange,omitempty\"`\n}\n"
  },
  {
    "path": "lsp/protocol/workspace_test.go",
    "content": "// SPDX-FileCopyrightText: 2020 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\npackage protocol\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"encoding/json\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\n\t\"github.com/a-h/templ/lsp/uri\"\n)\n\nfunc TestWorkspaceFolder(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"uri\":\"/path/to/workspace\",\"name\":\"testWorkspace\"}`\n\t\twantInvalid = `{\"uri\":\"/path/to/invalid\",\"name\":\"invalidWorkspace\"}`\n\t)\n\twantType := WorkspaceFolder{\n\t\tURI:  \"/path/to/workspace\",\n\t\tName: \"testWorkspace\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceFolder\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceFolder\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceFolder\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDidChangeWorkspaceFoldersParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"event\":{\"added\":[{\"uri\":\"/path/to/addedWorkspace\",\"name\":\"testAddedWorkspace\"},{\"uri\":\"/path/to/addedWorkspace2\",\"name\":\"testAddedWorkspace2\"}],\"removed\":[{\"uri\":\"/path/to/removedWorkspace\",\"name\":\"testRemovedWorkspace\"},{\"uri\":\"/path/to/removedWorkspace2\",\"name\":\"testRemovedWorkspace2\"}]}}`\n\t\twantInvalid = `{\"event\":{\"added\":[{\"uri\":\"/path/to/addedInvalidWorkspace\",\"name\":\"invalidAddedWorkspace\"},{\"uri\":\"/path/to/addedInvalidWorkspace2\",\"name\":\"invalidAddedWorkspace2\"}],\"removed\":[{\"uri\":\"/path/to/removedInvalidWorkspace\",\"name\":\"invalidRemovedWorkspace\"},{\"uri\":\"/path/to/removedInvalidWorkspace2\",\"name\":\"invalidRemovedWorkspace2\"}]}}`\n\t)\n\twantType := DidChangeWorkspaceFoldersParams{\n\t\tEvent: WorkspaceFoldersChangeEvent{\n\t\t\tAdded: []WorkspaceFolder{\n\t\t\t\t{\n\t\t\t\t\tURI:  \"/path/to/addedWorkspace\",\n\t\t\t\t\tName: \"testAddedWorkspace\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tURI:  \"/path/to/addedWorkspace2\",\n\t\t\t\t\tName: \"testAddedWorkspace2\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tRemoved: []WorkspaceFolder{\n\t\t\t\t{\n\t\t\t\t\tURI:  \"/path/to/removedWorkspace\",\n\t\t\t\t\tName: \"testRemovedWorkspace\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tURI:  \"/path/to/removedWorkspace2\",\n\t\t\t\t\tName: \"testRemovedWorkspace2\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidChangeWorkspaceFoldersParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidChangeWorkspaceFoldersParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidChangeWorkspaceFoldersParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWorkspaceFoldersChangeEvent(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"added\":[{\"uri\":\"/path/to/addedWorkspace\",\"name\":\"testAddedWorkspace\"},{\"uri\":\"/path/to/addedWorkspace2\",\"name\":\"testAddedWorkspace2\"}],\"removed\":[{\"uri\":\"/path/to/removedWorkspace\",\"name\":\"testRemovedWorkspace\"},{\"uri\":\"/path/to/removedWorkspace2\",\"name\":\"testRemovedWorkspace2\"}]}`\n\t\twantInvalid = `{\"added\":[{\"uri\":\"/path/to/addedInvalidWorkspace\",\"name\":\"invalidAddedWorkspace\"},{\"uri\":\"/path/to/addedInvalidWorkspace2\",\"name\":\"invalidAddedWorkspace2\"}],\"removed\":[{\"uri\":\"/path/to/removedInvalidWorkspace\",\"name\":\"invalidRemovedWorkspace\"},{\"uri\":\"/path/to/removedInvalidWorkspace2\",\"name\":\"invalidRemovedWorkspace2\"}]}`\n\t)\n\twantType := WorkspaceFoldersChangeEvent{\n\t\tAdded: []WorkspaceFolder{\n\t\t\t{\n\t\t\t\tURI:  \"/path/to/addedWorkspace\",\n\t\t\t\tName: \"testAddedWorkspace\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tURI:  \"/path/to/addedWorkspace2\",\n\t\t\t\tName: \"testAddedWorkspace2\",\n\t\t\t},\n\t\t},\n\t\tRemoved: []WorkspaceFolder{\n\t\t\t{\n\t\t\t\tURI:  \"/path/to/removedWorkspace\",\n\t\t\t\tName: \"testRemovedWorkspace\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tURI:  \"/path/to/removedWorkspace2\",\n\t\t\t\tName: \"testRemovedWorkspace2\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceFoldersChangeEvent\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceFoldersChangeEvent\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceFoldersChangeEvent\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDidChangeConfigurationParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"settings\":\"testSettings\"}`\n\t\twantNilAll  = `{}`\n\t\twantInvalid = `{\"settings\":\"invalidSettings\"}`\n\t)\n\twantType := DidChangeConfigurationParams{\n\t\tSettings: \"testSettings\",\n\t}\n\twantTypeNilAll := DidChangeConfigurationParams{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidChangeConfigurationParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidChangeConfigurationParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidChangeConfigurationParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestConfigurationParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"items\":[{\"scopeUri\":\"file:///path/to/test.go\",\"section\":\"testSection\"}]}`\n\t\twantNilAll  = `{\"items\":[]}`\n\t\twantInvalid = `{\"items\":[{\"scopeUri\":\"file:///path/to/invalid.go\",\"section\":\"invalidSection\"}]}`\n\t)\n\twantType := ConfigurationParams{\n\t\tItems: []ConfigurationItem{\n\t\t\t{\n\t\t\t\tScopeURI: uri.File(\"/path/to/test.go\"),\n\t\t\t\tSection:  \"testSection\",\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := ConfigurationParams{\n\t\tItems: []ConfigurationItem{},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ConfigurationParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ConfigurationParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ConfigurationParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestConfigurationItem(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"scopeUri\":\"file:///path/to/test.go\",\"section\":\"testSection\"}`\n\t\twantNilAll  = `{}`\n\t\twantInvalid = `{\"scopeUri\":\"file:///path/to/invalid.go\",\"section\":\"invalidSection\"}`\n\t)\n\twantType := ConfigurationItem{\n\t\tScopeURI: uri.File(\"/path/to/test.go\"),\n\t\tSection:  \"testSection\",\n\t}\n\twantTypeNilAll := ConfigurationItem{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ConfigurationItem\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ConfigurationItem\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ConfigurationItem\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestDidChangeWatchedFilesParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"changes\":[{\"type\":2,\"uri\":\"file:///path/to/test.go\"}]}`\n\t\twantNilAll  = `{}`\n\t\twantInvalid = `{\"changes\":[{\"type\":3,\"uri\":\"file:///path/to/invalid.go\"}]}`\n\t)\n\twantType := DidChangeWatchedFilesParams{\n\t\tChanges: []*FileEvent{\n\t\t\t{\n\t\t\t\tType: FileChangeTypeChanged,\n\t\t\t\tURI:  uri.File(\"/path/to/test.go\"),\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := DidChangeWatchedFilesParams{}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidChangeWatchedFilesParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidChangeWatchedFilesParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidChangeWatchedFilesParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestFileEvent(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"type\":2,\"uri\":\"file:///path/to/test.go\"}`\n\t\twantInvalid = `{\"type\":3,\"uri\":\"file:///path/to/invalid.go\"}`\n\t)\n\twantType := FileEvent{\n\t\tType: FileChangeTypeChanged,\n\t\tURI:  uri.File(\"/path/to/test.go\"),\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          FileEvent\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             FileEvent\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got FileEvent\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestFileChangeType_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    FileChangeType\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"Created\",\n\t\t\tk:    FileChangeTypeCreated,\n\t\t\twant: \"Created\",\n\t\t},\n\t\t{\n\t\t\tname: \"Changed\",\n\t\t\tk:    FileChangeTypeChanged,\n\t\t\twant: \"Changed\",\n\t\t},\n\t\t{\n\t\t\tname: \"Deleted\",\n\t\t\tk:    FileChangeTypeDeleted,\n\t\t\twant: \"Deleted\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    FileChangeType(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"FileChangeType.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDidChangeWatchedFilesRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"watchers\":[{\"globPattern\":\"*\",\"kind\":2}]}`\n\t\twantNilAll  = `{\"watchers\":[{\"globPattern\":\"*\"}]}`\n\t\twantInvalid = `{\"watchers\":[{\"globPattern\":\"?\",\"kind\":1}]}`\n\t)\n\twantType := DidChangeWatchedFilesRegistrationOptions{\n\t\tWatchers: []FileSystemWatcher{\n\t\t\t{\n\t\t\t\tGlobPattern: \"*\",\n\t\t\t\tKind:        WatchKindChange,\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := DidChangeWatchedFilesRegistrationOptions{\n\t\tWatchers: []FileSystemWatcher{\n\t\t\t{\n\t\t\t\tGlobPattern: \"*\",\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          DidChangeWatchedFilesRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             DidChangeWatchedFilesRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got DidChangeWatchedFilesRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestWatchKind_String(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname string\n\t\tk    WatchKind\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"CreateWatch\",\n\t\t\tk:    WatchKindCreate,\n\t\t\twant: \"Create\",\n\t\t},\n\t\t{\n\t\t\tname: \"ChangeWatch\",\n\t\t\tk:    WatchKindChange,\n\t\t\twant: \"Change\",\n\t\t},\n\t\t{\n\t\t\tname: \"DeleteWatch\",\n\t\t\tk:    WatchKindDelete,\n\t\t\twant: \"Delete\",\n\t\t},\n\t\t{\n\t\t\tname: \"Unknown\",\n\t\t\tk:    WatchKind(0),\n\t\t\twant: \"0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif got := tt.k.String(); got != tt.want {\n\t\t\t\tt.Errorf(\"WatchKind.String() = %v, want %v\", tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestWorkspaceSymbolParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken      = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\twantPartialResultToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"partialResultToken\":\"` + wantPartialResultToken + `\",\"query\":\"testQuery\"}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + wantPartialResultToken + `\",\"partialResultToken\":\"` + wantWorkDoneToken + `\",\"query\":\"invalidQuery\"}`\n\t)\n\twantType := WorkspaceSymbolParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tPartialResultParams: PartialResultParams{\n\t\t\tPartialResultToken: NewProgressToken(wantPartialResultToken),\n\t\t},\n\t\tQuery: \"testQuery\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          WorkspaceSymbolParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             WorkspaceSymbolParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got WorkspaceSymbolParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif partialResultToken := got.PartialResultToken; partialResultToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(partialResultToken), wantPartialResultToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestExecuteCommandParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twantWorkDoneToken    = \"156edea9-9d8d-422f-b7ee-81a84594afbb\"\n\t\tinvalidWorkDoneToken = \"dd134d84-c134-4d7a-a2a3-f8af3ef4a568\"\n\t)\n\tconst (\n\t\twant        = `{\"workDoneToken\":\"` + wantWorkDoneToken + `\",\"command\":\"testCommand\",\"arguments\":[\"testArguments\"]}`\n\t\twantNilAll  = `{\"command\":\"testCommand\"}`\n\t\twantInvalid = `{\"workDoneToken\":\"` + invalidWorkDoneToken + `\",\"command\":\"invalidCommand\",\"arguments\":[\"invalidArguments\"]}`\n\t)\n\twantType := ExecuteCommandParams{\n\t\tWorkDoneProgressParams: WorkDoneProgressParams{\n\t\t\tWorkDoneToken: NewProgressToken(wantWorkDoneToken),\n\t\t},\n\t\tCommand: \"testCommand\",\n\t\tArguments: []any{\n\t\t\t\"testArguments\",\n\t\t},\n\t}\n\twantTypeNilAll := ExecuteCommandParams{\n\t\tCommand: \"testCommand\",\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ExecuteCommandParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ExecuteCommandParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ExecuteCommandParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got, cmpopts.IgnoreTypes(WorkDoneProgressParams{}, PartialResultParams{})); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\n\t\t\t\tif workDoneToken := got.WorkDoneToken; workDoneToken != nil {\n\t\t\t\t\tif diff := cmp.Diff(fmt.Sprint(workDoneToken), wantWorkDoneToken); (diff != \"\") != tt.wantErr {\n\t\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestExecuteCommandRegistrationOptions(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"commands\":[\"testCommand\",\"testCommand2\"]}`\n\t\twantInvalid = `{\"commands\":[\"invalidCommand\"]}`\n\t)\n\twantType := ExecuteCommandRegistrationOptions{\n\t\tCommands: []string{\n\t\t\t\"testCommand\",\n\t\t\t\"testCommand2\",\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ExecuteCommandRegistrationOptions\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ExecuteCommandRegistrationOptions\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ExecuteCommandRegistrationOptions\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestApplyWorkspaceEditParams(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"label\":\"testLabel\",\"edit\":{\"changes\":{\"file:///path/to/basic.go\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]},\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}]}}`\n\t\twantNilAll  = `{\"edit\":{\"changes\":{\"file:///path/to/basic.go\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]},\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/basic.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":25,\"character\":1},\"end\":{\"line\":27,\"character\":3}},\"newText\":\"foo bar\"}]}]}}`\n\t\twantInvalid = `{\"label\":\"testLabel\",\"edit\":{\"changes\":{\"file:///path/to/basic_gen.go\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\"}]},\"documentChanges\":[{\"textDocument\":{\"uri\":\"file:///path/to/basic_gen.go\",\"version\":10},\"edits\":[{\"range\":{\"start\":{\"line\":2,\"character\":1},\"end\":{\"line\":3,\"character\":2}},\"newText\":\"foo bar\"}]}]}}`\n\t)\n\twantType := ApplyWorkspaceEditParams{\n\t\tLabel: \"testLabel\",\n\t\tEdit: WorkspaceEdit{\n\t\t\tChanges: map[uri.URI][]TextEdit{\n\t\t\t\turi.File(\"/path/to/basic.go\"): {\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tDocumentChanges: []TextDocumentEdit{\n\t\t\t\t{\n\t\t\t\t\tTextDocument: OptionalVersionedTextDocumentIdentifier{\n\t\t\t\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tVersion: NewVersion(int32(10)),\n\t\t\t\t\t},\n\t\t\t\t\tEdits: []TextEdit{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\twantTypeNilAll := ApplyWorkspaceEditParams{\n\t\tEdit: WorkspaceEdit{\n\t\t\tChanges: map[uri.URI][]TextEdit{\n\t\t\t\turi.File(\"/path/to/basic.go\"): {\n\t\t\t\t\t{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tDocumentChanges: []TextDocumentEdit{\n\t\t\t\t{\n\t\t\t\t\tTextDocument: OptionalVersionedTextDocumentIdentifier{\n\t\t\t\t\t\tTextDocumentIdentifier: TextDocumentIdentifier{\n\t\t\t\t\t\t\tURI: uri.File(\"/path/to/basic.go\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tVersion: NewVersion(int32(10)),\n\t\t\t\t\t},\n\t\t\t\t\tEdits: []TextEdit{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tStart: Position{\n\t\t\t\t\t\t\t\t\tLine:      25,\n\t\t\t\t\t\t\t\t\tCharacter: 1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tEnd: Position{\n\t\t\t\t\t\t\t\t\tLine:      27,\n\t\t\t\t\t\t\t\t\tCharacter: 3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tNewText: \"foo bar\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ApplyWorkspaceEditParams\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"ValidNilAll\",\n\t\t\t\tfield:          wantTypeNilAll,\n\t\t\t\twant:           wantNilAll,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ApplyWorkspaceEditParams\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"ValidNilAll\",\n\t\t\t\tfield:            wantNilAll,\n\t\t\t\twant:             wantTypeNilAll,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ApplyWorkspaceEditParams\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestApplyWorkspaceEditResponse(t *testing.T) {\n\tt.Parallel()\n\n\tconst (\n\t\twant        = `{\"applied\":true,\"failureReason\":\"testFailureReason\",\"failedChange\":1}`\n\t\twantInvalid = `{\"applied\":false}`\n\t)\n\twantType := ApplyWorkspaceEditResponse{\n\t\tApplied:       true,\n\t\tFailureReason: \"testFailureReason\",\n\t\tFailedChange:  1,\n\t}\n\n\tt.Run(\"Marshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname           string\n\t\t\tfield          ApplyWorkspaceEditResponse\n\t\t\twant           string\n\t\t\twantMarshalErr bool\n\t\t\twantErr        bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:           \"Valid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           want,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid\",\n\t\t\t\tfield:          wantType,\n\t\t\t\twant:           wantInvalid,\n\t\t\t\twantMarshalErr: false,\n\t\t\t\twantErr:        true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tgot, err := json.Marshal(&tt.field)\n\t\t\t\tif (err != nil) != tt.wantMarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, string(got)); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"Unmarshal\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname             string\n\t\t\tfield            string\n\t\t\twant             ApplyWorkspaceEditResponse\n\t\t\twantUnmarshalErr bool\n\t\t\twantErr          bool\n\t\t}{\n\t\t\t{\n\t\t\t\tname:             \"Valid\",\n\t\t\t\tfield:            want,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:             \"Invalid\",\n\t\t\t\tfield:            wantInvalid,\n\t\t\t\twant:             wantType,\n\t\t\t\twantUnmarshalErr: false,\n\t\t\t\twantErr:          true,\n\t\t\t},\n\t\t}\n\t\tfor _, tt := range tests {\n\t\t\ttt := tt\n\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\n\t\t\t\tvar got ApplyWorkspaceEditResponse\n\t\t\t\tif err := json.Unmarshal([]byte(tt.field), &got); (err != nil) != tt.wantUnmarshalErr {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\n\t\t\t\tif diff := cmp.Diff(tt.want, got); (diff != \"\") != tt.wantErr {\n\t\t\t\t\tt.Errorf(\"%s: wantErr: %t\\n(-want +got)\\n%s\", tt.name, tt.wantErr, diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "lsp/uri/uri.go",
    "content": "// Copyright 2019 The Go Language Server Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage uri\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nconst (\n\t// FileScheme schema of filesystem path.\n\tFileScheme = \"file\"\n\n\t// HTTPScheme schema of http.\n\tHTTPScheme = \"http\"\n\n\t// HTTPSScheme schema of https.\n\tHTTPSScheme = \"https\"\n)\n\nconst (\n\thierPart = \"://\"\n)\n\n// URI Uniform Resource Identifier (URI) https://tools.ietf.org/html/rfc3986.\n//\n// This class is a simple parser which creates the basic component parts\n// (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation\n// and encoding.\n//\n//\t  foo://example.com:8042/over/there?name=ferret#nose\n//\t  \\_/   \\______________/\\_________/ \\_________/ \\__/\n//\t   |           |            |            |        |\n//\tscheme     authority       path        query   fragment\n//\t   |   _____________________|__\n//\t  / \\ /                        \\\n//\t  urn:example:animal:ferret:nose\ntype URI string\n\n// Filename returns the file path for the given URI.\n// It is an error to call this on a URI that is not a valid filename.\nfunc (u URI) Filename() string {\n\tfilename, err := filename(u)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn filepath.FromSlash(filename)\n}\n\n// ParseDocumentURI interprets a string as a DocumentURI, applying VS\n// Code workarounds; see [DocumentURI.UnmarshalText] for details.\n// If \"s\" is a file name, use [URIFromPath] instead.\nfunc ParseDocumentURI(s string) (URI, error) {\n\tif s == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\tif !strings.HasPrefix(s, \"file://\") {\n\t\treturn \"\", fmt.Errorf(\"DocumentURI scheme is not 'file': %s\", s)\n\t}\n\n\t// VS Code sends URLs with only two slashes,\n\t// which are invalid. golang/go#39789.\n\tif !strings.HasPrefix(s, \"file:///\") {\n\t\ts = \"file:///\" + s[len(\"file://\"):]\n\t}\n\n\t// Even though the input is a URI, it may not be in canonical form. VS Code\n\t// in particular over-escapes :, @, etc. Unescape and re-encode to canonicalize.\n\tpath, err := url.PathUnescape(s[len(\"file://\"):])\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// File URIs from Windows may have lowercase drive letters.\n\t// Since drive letters are guaranteed to be case insensitive,\n\t// we change them to uppercase to remain consistent.\n\t// For example, file:///c:/x/y/z becomes file:///C:/x/y/z.\n\tif isWindowsDriveURI(path) {\n\t\tpath = path[:1] + strings.ToUpper(string(path[1])) + path[2:]\n\t}\n\tu := url.URL{Scheme: FileScheme, Path: path}\n\treturn URI(u.String()), nil\n}\n\nfunc filename(uri URI) (string, error) {\n\tu, err := url.ParseRequestURI(string(uri))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to parse request URI: %w\", err)\n\t}\n\n\tif u.Scheme != FileScheme {\n\t\treturn \"\", fmt.Errorf(\"only file URIs are supported, got %v\", u.Scheme)\n\t}\n\n\tif isWindowsDriveURI(u.Path) {\n\t\tu.Path = u.Path[1:]\n\t}\n\n\treturn u.Path, nil\n}\n\n// New parses and creates a new URI from s.\nfunc New(s string) URI {\n\tif u, err := url.PathUnescape(s); err == nil {\n\t\ts = u\n\t}\n\n\tif strings.HasPrefix(s, FileScheme+hierPart) {\n\t\treturn URI(s)\n\t}\n\n\treturn File(s)\n}\n\n// URIFromPath returns DocumentURI for the supplied file path.\n// Given \"\", it returns \"\".\nfunc URIFromPath(path string) URI {\n\tif path == \"\" {\n\t\treturn \"\"\n\t}\n\tif !isWindowsDrivePath(path) {\n\t\tif abs, err := filepath.Abs(path); err == nil {\n\t\t\tpath = abs\n\t\t}\n\t}\n\t// Check the file path again, in case it became absolute.\n\tif isWindowsDrivePath(path) {\n\t\tpath = \"/\" + strings.ToUpper(string(path[0])) + path[1:]\n\t}\n\tpath = filepath.ToSlash(path)\n\tu := url.URL{\n\t\tScheme: FileScheme,\n\t\tPath:   path,\n\t}\n\treturn URI(u.String())\n}\n\n// File parses and creates a new filesystem URI from path.\nfunc File(path string) URI {\n\tif !isWindowsDrivePath(path) {\n\t\tif abs, err := filepath.Abs(path); err == nil {\n\t\t\tpath = abs\n\t\t}\n\t}\n\n\tif isWindowsDrivePath(path) {\n\t\tpath = \"/\" + path\n\t}\n\n\tpath = filepath.ToSlash(path)\n\tu := url.URL{\n\t\tScheme: FileScheme,\n\t\tPath:   path,\n\t}\n\n\treturn URI(u.String())\n}\n\n// Parse parses and creates a new URI from s.\nfunc Parse(s string) (u URI, err error) {\n\tus, err := url.Parse(s)\n\tif err != nil {\n\t\treturn u, fmt.Errorf(\"url.Parse: %w\", err)\n\t}\n\n\tswitch us.Scheme {\n\tcase FileScheme:\n\t\tut := url.URL{\n\t\t\tScheme:  FileScheme,\n\t\t\tPath:    us.Path,\n\t\t\tRawPath: filepath.FromSlash(us.Path),\n\t\t}\n\t\tu = URI(ut.String())\n\n\tcase HTTPScheme, HTTPSScheme:\n\t\tut := url.URL{\n\t\t\tScheme:   us.Scheme,\n\t\t\tHost:     us.Host,\n\t\t\tPath:     us.Path,\n\t\t\tRawQuery: us.Query().Encode(),\n\t\t\tFragment: us.Fragment,\n\t\t}\n\t\tu = URI(ut.String())\n\n\tdefault:\n\t\treturn u, errors.New(\"unknown scheme\")\n\t}\n\n\treturn\n}\n\n// From returns the new URI from args.\nfunc From(scheme, authority, path, query, fragment string) URI {\n\tswitch scheme {\n\tcase FileScheme:\n\t\tu := url.URL{\n\t\t\tScheme:  FileScheme,\n\t\t\tPath:    path,\n\t\t\tRawPath: filepath.FromSlash(path),\n\t\t}\n\t\treturn URI(u.String())\n\n\tcase HTTPScheme, HTTPSScheme:\n\t\tu := url.URL{\n\t\t\tScheme:   scheme,\n\t\t\tHost:     authority,\n\t\t\tPath:     path,\n\t\t\tRawQuery: url.QueryEscape(query),\n\t\t\tFragment: fragment,\n\t\t}\n\t\treturn URI(u.String())\n\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown scheme: %s\", scheme))\n\t}\n}\n\n// isWindowsDrivePath returns true if the file path is of the form used by Windows.\n//\n// We check if the path begins with a drive letter, followed by a \":\".\nfunc isWindowsDrivePath(path string) bool {\n\tif len(path) < 4 {\n\t\treturn false\n\t}\n\treturn unicode.IsLetter(rune(path[0])) && path[1] == ':'\n}\n\n// isWindowsDriveURI returns true if the file URI is of the format used by\n// Windows URIs. The url.Parse package does not specially handle Windows paths\n// (see https://golang.org/issue/6027). We check if the URI path has\n// a drive prefix (e.g. \"/C:\"). If so, we trim the leading \"/\".\nfunc isWindowsDriveURI(uri string) bool {\n\tif len(uri) < 4 {\n\t\treturn false\n\t}\n\treturn uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':'\n}\n"
  },
  {
    "path": "lsp/uri/uri_test.go",
    "content": "// Copyright 2019 The Go Language Server Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage uri\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestFile(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\tpath    string\n\t\twant    URI\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"ValidFileScheme\",\n\t\t\tpath:    \"/users/me/c#-projects/\",\n\t\t\twant:    URI(FileScheme + hierPart + \"/users/me/c%23-projects\"),\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"Invalid\",\n\t\t\tpath:    \"users-me-c#-projects\",\n\t\t\twant:    URI(\"\"),\n\t\t\twantErr: true,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif diff := cmp.Diff(File(tt.path), tt.want); (diff != \"\") != tt.wantErr {\n\t\t\t\tt.Errorf(\"%s: (-got, +want)\\n%s\", tt.name, diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestParse(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\ts    string\n\t\twant URI\n\t}{\n\t\t{\n\t\t\tname: \"ValidFileScheme\",\n\t\t\ts:    \"file://code.visualstudio.com/docs/extensions/overview.md\",\n\t\t\twant: URI(FileScheme + hierPart + \"/docs/extensions/overview.md\"),\n\t\t},\n\t\t{\n\t\t\tname: \"ValidHTTPScheme\",\n\t\t\ts:    \"http://code.visualstudio.com/docs/extensions/overview#frag\",\n\t\t\twant: URI(HTTPScheme + hierPart + \"code.visualstudio.com/docs/extensions/overview#frag\"),\n\t\t},\n\t\t{\n\t\t\tname: \"ValidHTTPSScheme\",\n\t\t\ts:    \"https://code.visualstudio.com/docs/extensions/overview#frag\",\n\t\t\twant: URI(HTTPSScheme + hierPart + \"code.visualstudio.com/docs/extensions/overview#frag\"),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tgot, err := Parse(tt.s)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif diff := cmp.Diff(got, tt.want); diff != \"\" {\n\t\t\t\tt.Errorf(\"%s: (-got, +want)\\n%s\", tt.name, diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestFrom(t *testing.T) {\n\ttype args struct {\n\t\tscheme    string\n\t\tauthority string\n\t\tpath      string\n\t\tquery     string\n\t\tfragment  string\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant URI\n\t}{\n\t\t{\n\t\t\tname: \"ValidFileScheme\",\n\t\t\targs: args{\n\t\t\t\tscheme:    \"file\",\n\t\t\t\tauthority: \"example.com\",\n\t\t\t\tpath:      \"/over/there\",\n\t\t\t\tquery:     \"name=ferret\",\n\t\t\t\tfragment:  \"nose\",\n\t\t\t},\n\t\t\twant: URI(FileScheme + hierPart + \"/over/there\"),\n\t\t},\n\t\t{\n\t\t\tname: \"ValidHTTPScheme\",\n\t\t\targs: args{\n\t\t\t\tscheme:    \"http\",\n\t\t\t\tauthority: \"example.com:8042\",\n\t\t\t\tpath:      \"/over/there\",\n\t\t\t\tquery:     \"name=ferret\",\n\t\t\t\tfragment:  \"nose\",\n\t\t\t},\n\t\t\twant: URI(HTTPScheme + hierPart + \"example.com:8042/over/there?name%3Dferret#nose\"),\n\t\t},\n\t\t{\n\t\t\tname: \"ValidHTTPSScheme\",\n\t\t\targs: args{\n\t\t\t\tscheme:    \"https\",\n\t\t\t\tauthority: \"example.com:8042\",\n\t\t\t\tpath:      \"/over/there\",\n\t\t\t\tquery:     \"name=ferret\",\n\t\t\t\tfragment:  \"nose\",\n\t\t\t},\n\t\t\twant: URI(HTTPSScheme + hierPart + \"example.com:8042/over/there?name%3Dferret#nose\"),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tif diff := cmp.Diff(From(tt.args.scheme, tt.args.authority, tt.args.path, tt.args.query, tt.args.fragment), tt.want); diff != \"\" {\n\t\t\t\tt.Errorf(\"%s: (-got, +want)\\n%s\", tt.name, diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "lsp/xcontext/xcontext.go",
    "content": "// Copyright 2020 The Go Language Server Authors\n// SPDX-License-Identifier: BSD-3-Clause\n\n// Package xcontext is a package to offer the extra functionality we need\n// from contexts that is not available from the standard context package.\npackage xcontext\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\n// Detach returns a context that keeps all the values of its parent context\n// but detaches from the cancellation and error handling.\nfunc Detach(ctx context.Context) context.Context { return detachedContext{ctx} }\n\ntype detachedContext struct{ parent context.Context }\n\nfunc (v detachedContext) Deadline() (time.Time, bool) { return time.Time{}, false }\nfunc (v detachedContext) Done() <-chan struct{}       { return nil }\nfunc (v detachedContext) Err() error                  { return nil }\nfunc (v detachedContext) Value(key any) any           { return v.parent.Value(key) }\n"
  },
  {
    "path": "once.go",
    "content": "package templ\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"sync/atomic\"\n)\n\n// onceHandleIndex is used to identify unique once handles in a program run.\nvar onceHandleIndex int64\n\ntype OnceOpt func(*OnceHandle)\n\n// WithOnceComponent sets the component to be rendered once per context.\n// This can be used instead of setting the children of the `Once` method,\n// for example, if creating a code component outside of a templ HTML template.\nfunc WithComponent(c Component) OnceOpt {\n\treturn func(o *OnceHandle) {\n\t\to.c = c\n\t}\n}\n\n// NewOnceHandle creates a OnceHandle used to ensure that the children of its\n// `Once` method are only rendered once per context.\nfunc NewOnceHandle(opts ...OnceOpt) *OnceHandle {\n\toh := &OnceHandle{\n\t\tid: atomic.AddInt64(&onceHandleIndex, 1),\n\t}\n\tfor _, opt := range opts {\n\t\topt(oh)\n\t}\n\treturn oh\n}\n\n// OnceHandle is used to ensure that the children of its `Once` method are are only\n// rendered once per context.\ntype OnceHandle struct {\n\t// id is used to identify which instance of the OnceHandle is being used.\n\t// The OnceHandle can't be an empty struct, because:\n\t//\n\t//  | Two distinct zero-size variables may\n\t//  | have the same address in memory\n\t//\n\t// https://go.dev/ref/spec#Size_and_alignment_guarantees\n\tid int64\n\t// c is the component to be rendered once per context.\n\t// if c is nil, the children of the `Once` method are rendered.\n\tc Component\n}\n\n// Once returns a component that renders its children once per context.\nfunc (o *OnceHandle) Once() Component {\n\treturn ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\t_, v := getContext(ctx)\n\t\tif v.getHasBeenRendered(o) {\n\t\t\treturn nil\n\t\t}\n\t\tv.setHasBeenRendered(o)\n\t\tif o.c != nil {\n\t\t\treturn o.c.Render(ctx, w)\n\t\t}\n\t\treturn GetChildren(ctx).Render(ctx, w)\n\t})\n}\n"
  },
  {
    "path": "once_test.go",
    "content": "package templ_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\ntype onceHandleTest struct {\n\tctx      context.Context\n\texpected string\n}\n\nfunc TestOnceHandle(t *testing.T) {\n\twithHello := templ.WithChildren(context.Background(), templ.Raw(\"hello\"))\n\ttests := []struct {\n\t\tname  string\n\t\ttests []onceHandleTest\n\t}{\n\t\t{\n\t\t\tname: \"renders nothing without children\",\n\t\t\ttests: []onceHandleTest{\n\t\t\t\t{\n\t\t\t\t\tctx:      context.Background(),\n\t\t\t\t\texpected: \"\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"children are rendered\",\n\t\t\ttests: []onceHandleTest{\n\t\t\t\t{\n\t\t\t\t\tctx:      templ.WithChildren(context.Background(), templ.Raw(\"hello\")),\n\t\t\t\t\texpected: \"hello\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"children are rendered once per context\",\n\t\t\ttests: []onceHandleTest{\n\t\t\t\t{\n\t\t\t\t\tctx:      withHello,\n\t\t\t\t\texpected: \"hello\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tctx:      withHello,\n\t\t\t\t\texpected: \"\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"different contexts have different once state\",\n\t\t\ttests: []onceHandleTest{\n\t\t\t\t{\n\t\t\t\t\tctx:      templ.WithChildren(context.Background(), templ.Raw(\"hello\")),\n\t\t\t\t\texpected: \"hello\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tctx:      templ.WithChildren(context.Background(), templ.Raw(\"hello2\")),\n\t\t\t\t\texpected: \"hello2\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tc := templ.NewOnceHandle().Once()\n\t\t\tfor i, test := range tt.tests {\n\t\t\t\tt.Run(fmt.Sprintf(\"render %d/%d\", i+1, len(tt.tests)), func(t *testing.T) {\n\t\t\t\t\thtml, err := templ.ToGoHTML(test.ctx, c)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t\tif diff := cmp.Diff(test.expected, string(html)); diff != \"\" {\n\t\t\t\t\t\tt.Errorf(\"unexpected diff:\\n%v\", diff)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\t}\n\tt.Run(\"each new handle manages different state\", func(t *testing.T) {\n\t\tctx := templ.WithChildren(context.Background(), templ.Raw(\"hello\"))\n\t\th1 := templ.NewOnceHandle()\n\t\tc1 := h1.Once()\n\t\th2 := templ.NewOnceHandle()\n\t\tc2 := h2.Once()\n\t\tc3 := h2.Once()\n\t\tvar w strings.Builder\n\t\tif err := c1.Render(ctx, &w); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif err := c2.Render(ctx, &w); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif err := c3.Render(ctx, &w); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(\"hellohello\", w.String()); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected diff:\\n%v\", diff)\n\t\t}\n\t})\n\tt.Run(\"a handle can be used to render a specific component\", func(t *testing.T) {\n\t\tctx := templ.WithChildren(context.Background(), templ.Raw(\"child\"))\n\t\to := templ.NewOnceHandle(templ.WithComponent(templ.Raw(\"c\"))).Once()\n\t\tvar w strings.Builder\n\t\tif err := o.Render(ctx, &w); err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(\"c\", w.String()); diff != \"\" {\n\t\t\tt.Errorf(\"unexpected diff:\\n%v\", diff)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "parser/v2/allocs_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n)\n\nfunc RunParserAllocTest[T any](t *testing.T, p parse.Parser[T], expectOK bool, maxAllocs int64, input string) {\n\tpi := parse.NewInput(input)\n\tactual := testing.AllocsPerRun(4, func() {\n\t\tpi.Seek(0)\n\t\t_, ok, err := p.Parse(pi)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"error parsing %T: %v\", p, err)\n\t\t}\n\t\tif ok != expectOK {\n\t\t\tt.Fatalf(\"failed to parse %T\", p)\n\t\t}\n\t})\n\n\t// Run the benchmark.\n\tif int64(actual) > maxAllocs {\n\t\tt.Fatalf(\"Expected allocs <= %d, got %d\", maxAllocs, int64(actual))\n\t}\n}\n"
  },
  {
    "path": "parser/v2/benchmarks_test.go",
    "content": "package parser\n\nimport (\n\t_ \"embed\"\n\t\"strings\"\n\t\"testing\"\n)\n\n//go:embed benchmarktestdata/benchmark.txt\nvar benchmarkTemplate string\n\nfunc BenchmarkParse(b *testing.B) {\n\tb.ReportAllocs()\n\tfor range b.N {\n\t\tif _, err := ParseString(benchmarkTemplate); err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t}\n}\n\nfunc BenchmarkFormat(b *testing.B) {\n\tb.ReportAllocs()\n\tsb := new(strings.Builder)\n\tfor range b.N {\n\t\ttf, err := ParseString(benchmarkTemplate)\n\t\tif err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t\tif err = tf.Write(sb); err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t\tsb.Reset()\n\t}\n}\n"
  },
  {
    "path": "parser/v2/benchmarktestdata/benchmark.txt",
    "content": "package benchmarktestdata\n\ntempl Benchmark() {\n\t\t\t\t<div>Hello</div>\n\t\t\t\t<br>\n\t\t\t\t<br>\n\t\t\t\t<br>\n\t\t\t\t</br>\n\t\t\t\t<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>\n\t\t\t\t<br>\n\t\t\t\t<br>\n\t\t\t\t<ul>\n\t\t\t\t<li>Item 1</li>\n\t\t\t\t<li>Item 2</li>\n\t\t\t\t<li>Item 3</li>\n\t\t\t\t</ul>\n}\n\n"
  },
  {
    "path": "parser/v2/calltemplateparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\nvar callTemplateExpression callTemplateExpressionParser\n\nvar callTemplateExpressionStart = parse.Or(parse.String(\"{! \"), parse.String(\"{!\"))\n\ntype callTemplateExpressionParser struct{}\n\nfunc (p callTemplateExpressionParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\tstart := pi.Position()\n\n\t// Check the prefix first.\n\tif _, ok, err = callTemplateExpressionStart.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Once we have a prefix, we must have an expression that returns a template.\n\tr := &CallTemplateExpression{}\n\tif r.Expression, err = parseGo(\"call template expression\", pi, goexpression.Expression); err != nil {\n\t\treturn\n\t}\n\n\t// Eat the final brace.\n\tif _, ok, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"call template expression: missing closing brace\", pi.Position())\n\t\treturn\n\t}\n\n\tr.Range = NewRange(start, pi.Position())\n\n\treturn r, true, nil\n}\n"
  },
  {
    "path": "parser/v2/calltemplateparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestCallTemplateExpressionParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *CallTemplateExpression\n\t}{\n\t\t{\n\t\t\tname:  \"call: simple\",\n\t\t\tinput: `{! Other(p.Test) }`,\n\t\t\texpected: &CallTemplateExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 18, Line: 0, Col: 18},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"call: simple, missing start space\",\n\t\t\tinput: `{!Other(p.Test) }`,\n\t\t\texpected: &CallTemplateExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 2,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"call: simple, missing start and end space\",\n\t\t\tinput: `{!Other(p.Test)}`,\n\t\t\texpected: &CallTemplateExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 2,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 16, Line: 0, Col: 16},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := callTemplateExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCallTemplateParserAllocsSkip(t *testing.T) {\n\tRunParserAllocTest(t, callTemplateExpression, false, 0, ``)\n}\n"
  },
  {
    "path": "parser/v2/childrenparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\nvar childrenExpressionParser = parse.StringFrom(\n\topenBraceWithOptionalPadding,\n\tparse.OptionalWhitespace,\n\tparse.String(\"children...\"),\n\tparse.OptionalWhitespace,\n\tcloseBraceWithOptionalPadding,\n)\n\nvar childrenExpression = parse.Func(func(in *parse.Input) (n Node, ok bool, err error) {\n\tstart := in.Position()\n\t_, ok, err = childrenExpressionParser.Parse(in)\n\tif err != nil || !ok {\n\t\treturn\n\t}\n\tr := &ChildrenExpression{\n\t\tRange: NewRange(start, in.Position()),\n\t}\n\treturn r, true, nil\n})\n"
  },
  {
    "path": "parser/v2/childrenparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestChildrenExpressionParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *ChildrenExpression\n\t}{\n\t\t{\n\t\t\tname:  \"standard\",\n\t\t\tinput: `{ children...}`,\n\t\t\texpected: &ChildrenExpression{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"condensed\",\n\t\t\tinput: `{children...}`,\n\t\t\texpected: &ChildrenExpression{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 13, Line: 0, Col: 13},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"extra spaces\",\n\t\t\tinput: `{  children...  }`,\n\t\t\texpected: &ChildrenExpression{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := childrenExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestChildrenExpressionParserAllocsOK(t *testing.T) {\n\tRunParserAllocTest(t, childrenExpression, true, 3, `{ children... }`)\n}\n\nfunc TestChildrenExpressionParserAllocsSkip(t *testing.T) {\n\tRunParserAllocTest(t, childrenExpression, false, 2, ``)\n}\n"
  },
  {
    "path": "parser/v2/conditionalattributeparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\nvar conditionalAttribute parse.Parser[*ConditionalAttribute] = conditionalAttributeParser{}\n\ntype conditionalAttributeParser struct{}\n\nfunc (conditionalAttributeParser) Parse(pi *parse.Input) (r *ConditionalAttribute, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// Strip leading whitespace and look for `if `.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\treturn\n\t}\n\tattrStart := pi.Index()\n\tif !peekPrefix(pi, \"if \") {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Parse the Go if expression.\n\tr = &ConditionalAttribute{}\n\tif r.Expression, err = parseGo(\"if attribute\", pi, goexpression.If); err != nil {\n\t\treturn\n\t}\n\n\t// Eat \" {\\n\".\n\tif _, ok, err = openBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"attribute if: unterminated (missing closing '{\\n')\", pi.PositionAt(start))\n\t\treturn\n\t}\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\treturn\n\t}\n\n\t// Read the 'Then' attributes.\n\t// If there's no match, there's a problem reading the attributes.\n\tif r.Then, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"attribute if: expected attributes in block, but none were found\", pi.Position())\n\t\treturn\n\t}\n\n\tif len(r.Then) == 0 {\n\t\terr = parse.Error(\"attribute if: invalid content or no attributes were found in the if block\", pi.Position())\n\t\treturn\n\t}\n\n\t// Read the optional 'Else' Nodes.\n\tif r.Else, ok, err = attributeElseExpression.Parse(pi); err != nil {\n\t\treturn\n\t}\n\tif ok && len(r.Else) == 0 {\n\t\terr = parse.Error(\"attribute if: invalid content or no attributes were found in the else block\", pi.Position())\n\t\treturn\n\t}\n\n\t// Clear any optional whitespace.\n\t_, _, _ = parse.OptionalWhitespace.Parse(pi)\n\n\t// Read the required closing brace.\n\tif _, ok, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"attribute if: missing end (expected '}')\", pi.Position())\n\t\treturn\n\t}\n\tr.Range = NewRange(pi.PositionAt(attrStart), pi.Position())\n\n\treturn r, true, nil\n}\n\nvar attributeElseExpression parse.Parser[[]Attribute] = attributeElseExpressionParser{}\n\ntype attributeElseExpressionParser struct{}\n\nfunc (attributeElseExpressionParser) Parse(in *parse.Input) (r []Attribute, ok bool, err error) {\n\tstart := in.Index()\n\n\t// Strip any initial whitespace.\n\t_, _, _ = parse.OptionalWhitespace.Parse(in)\n\n\t// } else {\n\tvar endElseParser = parse.All(\n\t\tparse.Rune('}'),\n\t\tparse.OptionalWhitespace,\n\t\tparse.String(\"else\"),\n\t\tparse.OptionalWhitespace,\n\t\tparse.Rune('{'))\n\tif _, ok, err = endElseParser.Parse(in); err != nil || !ok {\n\t\tin.Seek(start)\n\t\treturn\n\t}\n\n\t// Else contents\n\tif r, ok, err = (attributesParser{}).Parse(in); err != nil || !ok {\n\t\terr = parse.Error(\"attribute if: expected attributes in else block, but none were found\", in.Position())\n\t\treturn\n\t}\n\n\treturn r, true, nil\n}\n"
  },
  {
    "path": "parser/v2/cssparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\n// CSS.\n\n// CSS Parser.\nvar cssParser = parse.Func(func(pi *parse.Input) (r *CSSTemplate, ok bool, err error) {\n\tfrom := pi.Position()\n\n\tr = &CSSTemplate{\n\t\tProperties: []CSSProperty{},\n\t}\n\tdefer func() {\n\t\tr.Range = NewRange(from, pi.Position())\n\t}()\n\n\t// Parse the name.\n\tvar exp cssExpression\n\tif exp, ok, err = cssExpressionParser.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\tr.Name = exp.Name\n\tr.Expression = exp.Expression\n\n\tfor {\n\t\tvar cssProperty CSSProperty\n\n\t\t// Try for an expression CSS declaration.\n\t\t// background-color: { constants.BackgroundColor };\n\t\tcssProperty, ok, err = expressionCSSPropertyParser.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif ok {\n\t\t\tr.Properties = append(r.Properties, cssProperty)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Try for a constant CSS declaration.\n\t\t// color: #ffffff;\n\t\tcssProperty, ok, err = constantCSSPropertyParser.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif ok {\n\t\t\tr.Properties = append(r.Properties, cssProperty)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Eat any whitespace.\n\t\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\t\treturn\n\t\t}\n\n\t\t// Try for }\n\t\tif _, ok, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\t\terr = parse.Error(\"css property expression: missing closing brace\", pi.Position())\n\t\t\treturn\n\t\t}\n\n\t\treturn r, true, nil\n\t}\n})\n\n// css Func() {\ntype cssExpression struct {\n\tExpression Expression\n\tName       string\n}\n\nvar cssExpressionParser = parse.Func(func(pi *parse.Input) (r cssExpression, ok bool, err error) {\n\tstart := pi.Index()\n\n\tif !peekPrefix(pi, \"css \") {\n\t\treturn r, false, nil\n\t}\n\n\t// Once we have the prefix, everything to the brace is Go.\n\t// e.g.\n\t// css (x []string) Test() {\n\t// becomes:\n\t// func (x []string) Test() templ.CSSComponent {\n\tif r.Name, r.Expression, err = parseCSSFuncDecl(pi); err != nil {\n\t\treturn r, false, err\n\t}\n\n\t// Eat \" {\\n\".\n\tif _, ok, err = parse.All(openBraceWithOptionalPadding, parse.NewLine).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"css expression: parameters missing open bracket\", pi.PositionAt(start))\n\t\treturn\n\t}\n\n\treturn r, true, nil\n})\n\n// CSS property name parser.\nvar cssPropertyNameFirst = \"abcdefghijklmnopqrstuvwxyz-\"\nvar cssPropertyNameSubsequent = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-\"\nvar cssPropertyNameParser = parse.Func(func(in *parse.Input) (name string, ok bool, err error) {\n\tstart := in.Position()\n\tvar prefix, suffix string\n\tif prefix, ok, err = parse.RuneIn(cssPropertyNameFirst).Parse(in); err != nil || !ok {\n\t\treturn\n\t}\n\tif suffix, ok, err = parse.StringUntil(parse.RuneNotIn(cssPropertyNameSubsequent)).Parse(in); err != nil || !ok {\n\t\tin.Seek(start.Index)\n\t\treturn\n\t}\n\tif len(suffix)+1 > 128 {\n\t\tok = false\n\t\terr = parse.Error(\"css property names must be < 128 characters long\", in.Position())\n\t\treturn\n\t}\n\treturn prefix + suffix, true, nil\n})\n\n// background-color: {%= constants.BackgroundColor %};\nvar expressionCSSPropertyParser = parse.Func(func(pi *parse.Input) (r *ExpressionCSSProperty, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// Optional whitespace.\n\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\t// Property name.\n\tr = &ExpressionCSSProperty{}\n\tif r.Name, ok, err = cssPropertyNameParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\t// <space>:<space>\n\tif _, ok, err = parse.All(parse.OptionalWhitespace, parse.Rune(':'), parse.OptionalWhitespace).Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// { string }\n\tvar se Node\n\tif se, ok, err = stringExpression.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\tr.Value = se.(*StringExpression)\n\n\t// ;\n\tif _, ok, err = parse.String(\";\").Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"missing expected semicolon (;)\", pi.Position())\n\t\treturn\n\t}\n\t// \\n\n\tif _, ok, err = parse.NewLine.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"missing expected linebreak\", pi.Position())\n\t\treturn\n\t}\n\n\treturn r, true, nil\n})\n\n// background-color: #ffffff;\nvar constantCSSPropertyParser = parse.Func(func(pi *parse.Input) (r *ConstantCSSProperty, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// Optional whitespace.\n\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\t// Property name.\n\tr = &ConstantCSSProperty{}\n\tif r.Name, ok, err = cssPropertyNameParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\t// <space>:<space>\n\tif _, ok, err = parse.All(parse.OptionalWhitespace, parse.Rune(':'), parse.OptionalWhitespace).Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Everything until ';\\n'\n\tuntilEnd := parse.All(\n\t\tparse.OptionalWhitespace,\n\t\tparse.Rune(';'),\n\t\tparse.NewLine,\n\t)\n\tif r.Value, ok, err = parse.StringUntil(untilEnd).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"missing expected semicolon and linebreak (;\\\\n\", pi.Position())\n\t\treturn\n\t}\n\n\t// Chomp the ;\\n\n\tif _, ok, err = untilEnd.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"failed to chomp semicolon and linebreak (;\\\\n)\", pi.Position())\n\t\treturn\n\t}\n\n\treturn r, true, nil\n})\n"
  },
  {
    "path": "parser/v2/cssparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestExpressionCSSPropertyParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *ExpressionCSSProperty\n\t}{\n\t\t{\n\t\t\tname:  \"css: single constant property\",\n\t\t\tinput: `background-color: { constants.BackgroundColor };`,\n\t\t\texpected: &ExpressionCSSProperty{\n\t\t\t\tName: \"background-color\",\n\t\t\t\tValue: &StringExpression{\n\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\tValue: \"constants.BackgroundColor\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\tIndex: 20,\n\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\tCol:   20,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\tIndex: 45,\n\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\tCol:   45,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"css: single constant property with windows newlines\",\n\t\t\tinput: \"background-color:\\r\\n{ constants.BackgroundColor };\\r\\n\",\n\t\t\texpected: &ExpressionCSSProperty{\n\t\t\t\tName: \"background-color\",\n\t\t\t\tValue: &StringExpression{\n\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\tValue: \"constants.BackgroundColor\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\tIndex: 21,\n\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\tIndex: 46,\n\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\tCol:   27,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input + \"\\n\")\n\t\t\tresult, ok, err := expressionCSSPropertyParser.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestConstantCSSPropertyParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *ConstantCSSProperty\n\t}{\n\t\t{\n\t\t\tname:  \"css: single constant property\",\n\t\t\tinput: `background-color: #ffffff;`,\n\t\t\texpected: &ConstantCSSProperty{\n\t\t\t\tName:  \"background-color\",\n\t\t\t\tValue: \"#ffffff\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"css: single constant webkit property\",\n\t\t\tinput: `-webkit-text-stroke-color: #ffffff;`,\n\t\t\texpected: &ConstantCSSProperty{\n\t\t\t\tName:  \"-webkit-text-stroke-color\",\n\t\t\t\tValue: \"#ffffff\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input + \"\\n\")\n\t\t\tresult, ok, err := constantCSSPropertyParser.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCSSParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *CSSTemplate\n\t}{\n\t\t{\n\t\t\tname: \"css: no parameters, no content\",\n\t\t\tinput: `css Name() {\n}`,\n\t\t\texpected: &CSSTemplate{\n\t\t\t\tName: \"Name\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 14, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProperties: []CSSProperty{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"css: without spaces\",\n\t\t\tinput: `css Name() {\n}`,\n\t\t\texpected: &CSSTemplate{\n\t\t\t\tName: \"Name\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 14, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProperties: []CSSProperty{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"css: single constant property\",\n\t\t\tinput: `css Name() {\nbackground-color: #ffffff;\n}`,\n\t\t\texpected: &CSSTemplate{\n\t\t\t\tName: \"Name\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 41, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProperties: []CSSProperty{\n\t\t\t\t\t&ConstantCSSProperty{\n\t\t\t\t\t\tName:  \"background-color\",\n\t\t\t\t\t\tValue: \"#ffffff\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"css: single expression property\",\n\t\t\tinput: `css Name() {\nbackground-color: { constants.BackgroundColor };\n}`,\n\t\t\texpected: &CSSTemplate{\n\t\t\t\tName: \"Name\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 63, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProperties: []CSSProperty{\n\t\t\t\t\t&ExpressionCSSProperty{\n\t\t\t\t\t\tName: \"background-color\",\n\t\t\t\t\t\tValue: &StringExpression{\n\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\tValue: \"constants.BackgroundColor\",\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 33,\n\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\tCol:   20,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 58,\n\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\tCol:   45,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"css: single expression with parameter\",\n\t\t\tinput: `css Name(prop string) {\nbackground-color: { prop };\n}`,\n\t\t\texpected: &CSSTemplate{\n\t\t\t\tName: \"Name\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 53, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(prop string)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 21,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   21,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProperties: []CSSProperty{\n\t\t\t\t\t&ExpressionCSSProperty{\n\t\t\t\t\t\tName: \"background-color\",\n\t\t\t\t\t\tValue: &StringExpression{\n\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\tValue: \"prop\",\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 44,\n\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\tCol:   20,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 48,\n\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\tCol:   24,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := cssParser.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/diagnostics.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n)\n\ntype diagnoser func(Node) ([]Diagnostic, error)\n\n// Diagnostic for template file.\ntype Diagnostic struct {\n\tMessage string\n\tRange   Range\n}\n\nfunc walkTemplate(t *TemplateFile, f func(Node) bool) {\n\tfor _, n := range t.Nodes {\n\t\thn, ok := n.(*HTMLTemplate)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\twalkNodes(hn.Children, f)\n\t}\n}\nfunc walkNodes(t []Node, f func(Node) bool) {\n\tfor _, n := range t {\n\t\tif !f(n) {\n\t\t\tcontinue\n\t\t}\n\t\tif h, ok := n.(CompositeNode); ok {\n\t\t\twalkNodes(h.ChildNodes(), f)\n\t\t}\n\t}\n}\n\nvar diagnosers = []diagnoser{\n\tuseOfLegacyCallSyntaxDiagnoser,\n}\n\nfunc Diagnose(t *TemplateFile) ([]Diagnostic, error) {\n\tvar diags []Diagnostic\n\tvar errs error\n\twalkTemplate(t, func(n Node) bool {\n\t\tfor _, d := range diagnosers {\n\t\t\tdiag, err := d(n)\n\t\t\tif err != nil {\n\t\t\t\terrs = errors.Join(errs, err)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tdiags = append(diags, diag...)\n\t\t}\n\t\treturn true\n\t})\n\treturn diags, errs\n}\n\nfunc useOfLegacyCallSyntaxDiagnoser(n Node) ([]Diagnostic, error) {\n\tif c, ok := n.(*CallTemplateExpression); ok {\n\t\treturn []Diagnostic{{\n\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\tRange:   c.Expression.Range,\n\t\t}}, nil\n\t}\n\treturn nil, nil\n}\n"
  },
  {
    "path": "parser/v2/diagnostics_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestDiagnose(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\ttemplate string\n\t\twant     []Diagnostic\n\t}{\n\t\t{\n\t\t\tname: \"no diagnostics\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\t<p>Hello, World!</p>\n}`,\n\t\t\twant: nil,\n\t\t},\n\n\t\t// useOfLegacyCallSyntaxDiagnoser\n\n\t\t{\n\t\t\tname: \"useOfLegacyCallSyntaxDiagnoser: template root\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\t{! templ.Raw(\"foo\") }\n}`,\n\t\t\twant: []Diagnostic{{\n\t\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\t\tRange:   Range{Position{39, 4, 4}, Position{55, 4, 20}},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"useOfLegacyCallSyntaxDiagnoser: in div\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\t<div>\n\t\t{! templ.Raw(\"foo\") }\n\t</div>\n}`,\n\t\t\twant: []Diagnostic{{\n\t\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\t\tRange:   Range{Position{47, 5, 5}, Position{63, 5, 21}},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"useOfLegacyCallSyntaxDiagnoser: in if\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\tif true {\n\t\t{! templ.Raw(\"foo\") }\n\t}\n}`,\n\t\t\twant: []Diagnostic{{\n\t\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\t\tRange:   Range{Position{51, 5, 5}, Position{67, 5, 21}},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"useOfLegacyCallSyntaxDiagnoser: in for\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\tfor i := range x {\n\t\t{! templ.Raw(\"foo\") }\n\t}\n}`,\n\t\t\twant: []Diagnostic{{\n\t\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\t\tRange:   Range{Position{60, 5, 5}, Position{76, 5, 21}},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"useOfLegacyCallSyntaxDiagnoser: in switch\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\tswitch x {\n\tcase 1:\n\t\t{! templ.Raw(\"foo\") }\n\tdefault:\n\t\t{! x }\n\t}\n}`,\n\t\t\twant: []Diagnostic{\n\t\t\t\t{\n\t\t\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\t\t\tRange:   Range{Position{61, 6, 5}, Position{77, 6, 21}},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\t\t\tRange:   Range{Position{95, 8, 5}, Position{96, 8, 6}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"useOfLegacyCallSyntaxDiagnoser: in block\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\t@layout(\"Home\") {\n\t\t{! templ.Raw(\"foo\") }\n\t}\n}`,\n\t\t\twant: []Diagnostic{{\n\t\t\t\tMessage: \"`{! foo }` syntax is deprecated. Use `@foo` syntax instead. Run `templ fmt .` to fix all instances.\",\n\t\t\t\tRange:   Range{Position{59, 5, 5}, Position{75, 5, 21}},\n\t\t\t}},\n\t\t},\n\t\t{\n\t\t\tname: \"voidElementWithChildrenDiagnoser: no diagnostics\",\n\t\t\ttemplate: `\npackage main\n\ntempl template () {\n\t<div>\n\t\t<input/>\n\t</div>\n}`,\n\t\t\twant: nil,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\ttf, err := ParseString(tt.template)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"ParseTemplateFile() error = %v\", err)\n\t\t\t}\n\t\t\tgot, err := Diagnose(tf)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"Diagnose() error = %v\", err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.want, got); diff != \"\" {\n\t\t\t\tt.Errorf(\"Diagnose() mismatch (-got +want):\\n%s\", diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/doctypeparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\nvar doctypeStartParser = parse.StringInsensitive(\"<!doctype \")\n\nvar untilLtOrGt = parse.Or(lt, gt)\nvar stringUntilLtOrGt = parse.StringUntil(untilLtOrGt)\n\nvar docType = parse.Func(func(pi *parse.Input) (n Node, ok bool, err error) {\n\tstart := pi.Position()\n\tif _, ok, err = doctypeStartParser.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Once a doctype has started, take everything until the end.\n\tr := &DocType{}\n\tif r.Value, ok, err = stringUntilLtOrGt.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"unclosed DOCTYPE\", start)\n\t\treturn\n\t}\n\n\t// Clear the final '>'.\n\tif _, ok, err = gt.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"unclosed DOCTYPE\", start)\n\t\treturn\n\t}\n\tr.Range = NewRange(start, pi.Position())\n\n\treturn r, true, nil\n})\n"
  },
  {
    "path": "parser/v2/doctypeparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestDocTypeParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *DocType\n\t}{\n\t\t{\n\t\t\tname:  \"HTML 5 doctype - uppercase\",\n\t\t\tinput: `<!DOCTYPE html>`,\n\t\t\texpected: &DocType{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{},\n\t\t\t\t\tTo:   Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t},\n\t\t\t\tValue: \"html\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"HTML 5 doctype - lowercase\",\n\t\t\tinput: `<!doctype html>`,\n\t\t\texpected: &DocType{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{},\n\t\t\t\t\tTo:   Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t},\n\t\t\t\tValue: \"html\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"HTML 4.01 doctype\",\n\t\t\tinput: `<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">`,\n\t\t\texpected: &DocType{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{},\n\t\t\t\t\tTo:   Position{Index: 102, Line: 0, Col: 102},\n\t\t\t\t},\n\t\t\t\tValue: `HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"`,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"XHTML 1.1\",\n\t\t\tinput: `<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">`,\n\t\t\texpected: &DocType{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{},\n\t\t\t\t\tTo:   Position{Index: 97, Line: 0, Col: 97},\n\t\t\t\t},\n\t\t\t\tValue: `html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"`,\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := docType.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDocTypeParserErrors(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected error\n\t}{\n\t\t{\n\t\t\tname:  \"doctype unclosed\",\n\t\t\tinput: `<!DOCTYPE html`,\n\t\t\texpected: parse.Error(\"unclosed DOCTYPE\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 0,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   0,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tname: \"doctype new tag started\",\n\t\t\tinput: `<!DOCTYPE html\n\t\t<div>`,\n\t\t\texpected: parse.Error(\"unclosed DOCTYPE\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 0,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   0,\n\t\t\t\t}),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, _, err := docType.Parse(input)\n\t\t\tif diff := cmp.Diff(tt.expected, err); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/elementparser.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\n// Element.\n\n// Element open tag.\ntype elementOpenTag struct {\n\tName        string\n\tAttributes  []Attribute\n\tIndentAttrs bool\n\tNameRange   Range\n\tVoid        bool\n}\n\nvar elementOpenTagParser = parse.Func(func(pi *parse.Input) (e elementOpenTag, matched bool, err error) {\n\tif next, _ := pi.Peek(2); len(next) < 2 || next[0] != '<' || next == \"<!\" || next == \"</\" {\n\t\t// This is not a tag, or it's a comment, doctype, or closing tag.\n\t\treturn e, false, nil\n\t}\n\n\t// <\n\tif _, matched, err = lt.Parse(pi); err != nil || !matched {\n\t\treturn\n\t}\n\n\t// Element name.\n\tl := pi.Position().Line\n\tif e.Name, matched, err = elementNameParser.Parse(pi); err != nil || !matched {\n\t\treturn e, true, err\n\t}\n\te.NameRange = NewRange(pi.PositionAt(pi.Index()-len(e.Name)), pi.Position())\n\n\tif e.Attributes, matched, err = (attributesParser{}).Parse(pi); err != nil || !matched {\n\t\treturn e, true, err\n\t}\n\n\t// If any attribute is not on the same line as the element name, indent them.\n\tif pi.Position().Line != l {\n\t\te.IndentAttrs = true\n\t}\n\n\t// Optional whitespace.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\treturn e, true, err\n\t}\n\n\t// />\n\tif _, matched, err = parse.String(\"/>\").Parse(pi); err != nil {\n\t\treturn e, true, err\n\t}\n\tif matched {\n\t\te.Void = true\n\t\treturn e, true, nil\n\t}\n\n\t// >\n\tif _, matched, err = gt.Parse(pi); err != nil {\n\t\treturn e, true, err\n\t}\n\n\t// If it's not a self-closing or complete open element, we have an error.\n\tif !matched {\n\t\terr = parse.Error(fmt.Sprintf(\"<%s>: malformed open element\", e.Name), pi.Position())\n\t\treturn\n\t}\n\n\treturn e, true, nil\n})\n\n// Attribute name.\nvar (\n\tattributeNameFirst      = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:_@\"\n\tattributeNameSubsequent = attributeNameFirst + \"-.0123456789*\"\n\tattributeNameParser     = parse.Func(func(in *parse.Input) (name string, ok bool, err error) {\n\t\tstart := in.Index()\n\t\tvar prefix, suffix string\n\t\tif prefix, ok, err = parse.RuneIn(attributeNameFirst).Parse(in); err != nil || !ok {\n\t\t\treturn\n\t\t}\n\t\tif suffix, ok, err = parse.StringUntil(parse.RuneNotIn(attributeNameSubsequent)).Parse(in); err != nil {\n\t\t\tin.Seek(start)\n\t\t\treturn\n\t\t}\n\t\tif len(suffix)+1 > 128 {\n\t\t\tok = false\n\t\t\terr = parse.Error(\"attribute names must be < 128 characters long\", in.Position())\n\t\t\treturn\n\t\t}\n\t\treturn prefix + suffix, true, nil\n\t})\n)\n\ntype attributeValueParser struct {\n\tEqualsAndQuote parse.Parser[string]\n\tSuffix         parse.Parser[string]\n\tUseSingleQuote bool\n}\n\nfunc (avp attributeValueParser) Parse(pi *parse.Input) (value string, ok bool, err error) {\n\tstart := pi.Index()\n\tif _, ok, err = avp.EqualsAndQuote.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\tif value, ok, err = parse.StringUntil(avp.Suffix).Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\tif _, ok, err = avp.Suffix.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\treturn value, true, nil\n}\n\n// Constant attribute.\nvar (\n\tattributeValueParsers = []attributeValueParser{\n\t\t// Double quoted.\n\t\t{EqualsAndQuote: parse.StringFrom(parse.OptionalWhitespace, parse.String(`=\"`)), Suffix: parse.String(`\"`), UseSingleQuote: false},\n\t\t// Single quoted.\n\t\t{EqualsAndQuote: parse.StringFrom(parse.OptionalWhitespace, parse.String(`='`)), Suffix: parse.String(`'`), UseSingleQuote: true},\n\t\t// Unquoted.\n\t\t// A valid unquoted attribute value in HTML is any string of text that is not an empty string,\n\t\t// and that doesn’t contain spaces, tabs, line feeds, form feeds, carriage returns, \", ', `, =, <, or >.\n\t\t{EqualsAndQuote: parse.StringFrom(parse.OptionalWhitespace, parse.String(\"=\")), Suffix: parse.Any(parse.RuneIn(\" \\t\\n\\r\\\"'`=<>/\"), parse.EOF[string]()), UseSingleQuote: false},\n\t}\n\tconstantAttributeParser = parse.Func(func(pi *parse.Input) (attr *ConstantAttribute, ok bool, err error) {\n\t\tstart := pi.Index()\n\n\t\t// Optional whitespace leader.\n\t\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\t\treturn\n\t\t}\n\n\t\tattrStart := pi.Index()\n\t\tattr = &ConstantAttribute{}\n\n\t\t// Attribute name.\n\t\tif attr.Key, ok, err = attributeKeyParser.Parse(pi); err != nil || !ok {\n\t\t\tpi.Seek(start)\n\t\t\treturn\n\t\t}\n\n\t\tfor _, p := range attributeValueParsers {\n\t\t\tattr.Value, ok, err = p.Parse(pi)\n\t\t\tif err != nil {\n\t\t\t\tpos := pi.Position()\n\t\t\t\tif pErr, isParseError := err.(parse.ParseError); isParseError {\n\t\t\t\t\tpos = pErr.Pos\n\t\t\t\t}\n\t\t\t\treturn attr, false, parse.Error(fmt.Sprintf(\"%s: %v\", attr.Key, err), pos)\n\t\t\t}\n\t\t\tif ok {\n\t\t\t\tattr.SingleQuote = p.UseSingleQuote\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif !ok {\n\t\t\tpi.Seek(start)\n\t\t\treturn attr, false, nil\n\t\t}\n\n\t\t// Only use single quotes if actually required, due to double quote in the value (prefer double quotes).\n\t\tattr.SingleQuote = attr.SingleQuote && strings.Contains(attr.Value, \"\\\"\")\n\t\tattr.Range = NewRange(pi.PositionAt(attrStart), pi.Position())\n\n\t\treturn attr, true, nil\n\t})\n)\n\nvar expressionAttributeKeyParser = parse.Func(func(pi *parse.Input) (attr AttributeKey, ok bool, err error) {\n\tstart := pi.Index()\n\t// Eat the first brace.\n\tif _, ok, err = openBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\tvar ek ExpressionAttributeKey\n\n\t// Expression.\n\tif ek.Expression, err = parseGoSliceArgs(pi); err != nil {\n\t\treturn attr, false, err\n\t}\n\n\t// Eat the Final brace.\n\tif _, ok, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"attribute key: missing closing brace\", pi.Position())\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\treturn ek, true, nil\n})\n\nvar constantAttributeKeyParser = parse.Func(func(pi *parse.Input) (k AttributeKey, ok bool, err error) {\n\tstart := pi.Index()\n\tn, ok, err := attributeNameParser.Parse(pi)\n\tif err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\tr := NewRange(pi.PositionAt(start), pi.Position())\n\tk = ConstantAttributeKey{Name: n, NameRange: r}\n\treturn k, true, nil\n})\n\nvar attributeKeyParser = parse.Any(constantAttributeKeyParser, expressionAttributeKeyParser)\n\n// BoolConstantAttribute.\nvar boolConstantAttributeParser = parse.Func(func(pi *parse.Input) (attr *BoolConstantAttribute, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// Optional whitespace leader.\n\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\tattrStart := pi.Index()\n\tattr = &BoolConstantAttribute{}\n\n\t// Attribute name.\n\tif attr.Key, ok, err = attributeKeyParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// We have a name, but if we have an equals sign, it's not a constant boolean attribute.\n\tnext, ok := pi.Peek(1)\n\tif !ok {\n\t\terr = parse.Error(\"boolConstantAttributeParser: unexpected EOF after attribute name\", pi.Position())\n\t\treturn\n\t}\n\tif next == \"=\" || next == \"?\" {\n\t\t// It's one of the other attribute types.\n\t\tpi.Seek(start)\n\t\treturn attr, false, nil\n\t}\n\tif next != \" \" && next != \"\\t\" && next != \"\\r\" && next != \"\\n\" && next != \"/\" && next != \">\" {\n\t\terr = parse.Error(fmt.Sprintf(\"boolConstantAttributeParser: expected attribute name to end with space, newline, '/>' or '>', but got %q\", next), pi.Position())\n\t\treturn attr, false, err\n\t}\n\tattr.Range = NewRange(pi.PositionAt(attrStart), pi.Position())\n\n\treturn attr, true, nil\n})\n\n// BoolExpressionAttribute.\nvar boolExpressionStart = parse.Or(parse.String(\"?={ \"), parse.String(\"?={\"))\n\nvar boolExpressionAttributeParser = parse.Func(func(pi *parse.Input) (r *BoolExpressionAttribute, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// Optional whitespace leader.\n\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\tattrStart := pi.Index()\n\tr = &BoolExpressionAttribute{}\n\n\t// Attribute name.\n\tif r.Key, ok, err = attributeKeyParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Check whether this is a boolean expression attribute.\n\tif _, ok, err = boolExpressionStart.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Once we have a prefix, we must have an expression that returns a boolean.\n\tif r.Expression, err = parseGo(\"boolean attribute\", pi, goexpression.Expression); err != nil {\n\t\treturn r, false, err\n\t}\n\n\t// Eat the Final brace.\n\tif _, ok, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"boolean expression: missing closing brace\", pi.Position())\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\tr.Range = NewRange(pi.PositionAt(attrStart), pi.Position())\n\n\treturn r, true, nil\n})\n\nvar expressionAttributeStartParser = parse.StringFrom(parse.OptionalWhitespace, parse.String(\"=\"), parse.OptionalWhitespace, parse.String(\"{\"), parse.OptionalWhitespace)\n\nvar expressionAttributeParser = parse.Func(func(pi *parse.Input) (attr *ExpressionAttribute, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// Optional whitespace leader.\n\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\tattr = &ExpressionAttribute{}\n\n\t// Attribute name.\n\tif attr.Key, ok, err = attributeKeyParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// ={\n\tif _, ok, err = expressionAttributeStartParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Expression.\n\tif attr.Expression, err = parseGoSliceArgs(pi); err != nil {\n\t\treturn attr, false, err\n\t}\n\n\t// Eat whitespace, plus the final brace.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\treturn attr, false, err\n\t}\n\tif _, ok, err = closeBrace.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"string expression attribute: missing closing brace\", pi.Position())\n\t\treturn\n\t}\n\n\treturn attr, true, nil\n})\n\nvar spreadAttributesParser = parse.Func(func(pi *parse.Input) (attr *SpreadAttributes, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// Optional whitespace leader.\n\tif _, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\tattrStart := pi.Index()\n\t// Eat the first brace.\n\tif _, ok, err = openBraceWithOptionalPadding.Parse(pi); err != nil ||\n\t\t!ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Expression.\n\tattr = &SpreadAttributes{}\n\tif attr.Expression, err = parseGo(\"spread attributes\", pi, goexpression.Expression); err != nil {\n\t\treturn\n\t}\n\n\t// Check if end of expression has \"...\" for spread.\n\tif !strings.HasSuffix(attr.Expression.Value, \"...\") {\n\t\tpi.Seek(start)\n\t\tok = false\n\t\treturn\n\t}\n\n\t// Remove extra spread characters from expression.\n\tattr.Expression.Value = strings.TrimSuffix(attr.Expression.Value, \"...\")\n\tattr.Expression.Range.To.Col -= 3\n\tattr.Expression.Range.To.Index -= 3\n\n\t// Eat the final brace.\n\tif _, ok, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"attribute spread expression: missing closing brace\", pi.Position())\n\t\treturn\n\t}\n\tattr.Range = NewRange(pi.PositionAt(attrStart), pi.Position())\n\n\treturn attr, true, nil\n})\n\n// Attributes.\ntype attributeParser struct{}\n\nfunc (attributeParser) Parse(in *parse.Input) (out Attribute, ok bool, err error) {\n\tif out, ok, err = spreadAttributesParser.Parse(in); err != nil || ok {\n\t\treturn\n\t}\n\tif out, ok, err = boolExpressionAttributeParser.Parse(in); err != nil || ok {\n\t\treturn\n\t}\n\tif out, ok, err = expressionAttributeParser.Parse(in); err != nil || ok {\n\t\treturn\n\t}\n\tif out, ok, err = conditionalAttribute.Parse(in); err != nil || ok {\n\t\treturn\n\t}\n\tif out, ok, err = boolConstantAttributeParser.Parse(in); err != nil || ok {\n\t\treturn\n\t}\n\tif out, ok, err = constantAttributeParser.Parse(in); err != nil || ok {\n\t\treturn\n\t}\n\treturn\n}\n\nvar attribute attributeParser\n\ntype attributesParser struct{}\n\nfunc (attributesParser) Parse(in *parse.Input) (attributes []Attribute, ok bool, err error) {\n\tfor {\n\t\tvar attr Attribute\n\t\tattr, ok, err = attribute.Parse(in)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\tattributes = append(attributes, attr)\n\t}\n\treturn attributes, true, nil\n}\n\n// Element name.\nvar (\n\telementNameFirst      = \"abcdefghijklmnopqrstuvwxyz\"\n\telementNameSubsequent = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-:\"\n\telementNameParser     = parse.Func(func(in *parse.Input) (name string, ok bool, err error) {\n\t\tstart := in.Index()\n\t\tvar prefix, suffix string\n\t\tif prefix, ok, err = parse.RuneIn(elementNameFirst).Parse(in); err != nil || !ok {\n\t\t\treturn\n\t\t}\n\t\tif suffix, ok, err = parse.StringUntil(parse.RuneNotIn(elementNameSubsequent)).Parse(in); err != nil || !ok {\n\t\t\tin.Seek(start)\n\t\t\treturn\n\t\t}\n\t\tif len(suffix)+1 > 128 {\n\t\t\tok = false\n\t\t\terr = parse.Error(\"element names must be < 128 characters long\", in.Position())\n\t\t\treturn\n\t\t}\n\t\treturn prefix + suffix, true, nil\n\t})\n)\n\n// Void element closer.\nvar voidElementCloser voidElementCloserParser\n\ntype voidElementCloserParser struct{}\n\nvar voidElementCloseTags = []string{\"</area>\", \"</base>\", \"</br>\", \"</col>\", \"</command>\", \"</embed>\", \"</hr>\", \"</img>\", \"</input>\", \"</keygen>\", \"</link>\", \"</meta>\", \"</param>\", \"</source>\", \"</track>\", \"</wbr>\"}\n\nfunc (voidElementCloserParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\tvar ve string\n\tfor _, ve = range voidElementCloseTags {\n\t\ts, canPeekLen := pi.Peek(len(ve))\n\t\tif !canPeekLen {\n\t\t\tcontinue\n\t\t}\n\t\tif !strings.EqualFold(s, ve) {\n\t\t\tcontinue\n\t\t}\n\t\t// Found a match.\n\t\tok = true\n\t\tbreak\n\t}\n\tif !ok {\n\t\treturn nil, false, nil\n\t}\n\tpi.Take(len(ve))\n\treturn nil, true, nil\n}\n\n// Element.\nvar element elementParser\n\ntype elementParser struct{}\n\nfunc (elementParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\tstart := pi.Position()\n\n\tif prefix, _ := pi.Peek(len(\"<script\")); prefix == \"<script\" {\n\t\t// This is a script element, which has special handling and should\n\t\t// be parsed by a different parser to this one.\n\t\treturn nil, false, nil\n\t}\n\n\t// Check the open tag.\n\tvar ot elementOpenTag\n\tif ot, ok, err = elementOpenTagParser.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\tr := &Element{\n\t\tName:        ot.Name,\n\t\tAttributes:  ot.Attributes,\n\t\tIndentAttrs: ot.IndentAttrs,\n\t\tNameRange:   ot.NameRange,\n\t}\n\n\t// Once we've got an open tag, the rest must be present.\n\tl := pi.Position().Line\n\n\t// If the element is self-closing, even if it's not really a void element (br, hr etc.), we can return early.\n\tif ot.Void || r.IsVoidElement() {\n\t\t// Escape early, no need to try to parse children for self-closing elements.\n\t\treturn addTrailingSpaceAndValidate(start, r, pi)\n\t}\n\n\t// Parse children.\n\tcloser := StripType(parse.All(parse.String(\"</\"), parse.String(ot.Name), parse.Rune('>')))\n\ttnp := newTemplateNodeParser(closer, fmt.Sprintf(\"<%s>: close tag\", ot.Name))\n\tnodes, _, err := tnp.Parse(pi)\n\tif err != nil {\n\t\tnotFoundErr, isNotFoundError := err.(UntilNotFoundError)\n\t\tif isNotFoundError {\n\t\t\terr = notFoundErr.ParseError\n\t\t}\n\t\t// If we got any nodes, take them, because the LSP might want to use them.\n\t\tr.Children = nodes.Nodes\n\t\treturn r, true, err\n\t}\n\tr.Children = nodes.Nodes\n\t// If the children are not all on the same line, indent them.\n\tif l != pi.Position().Line {\n\t\tr.IndentChildren = true\n\t}\n\n\t// Close tag.\n\t_, ok, err = closer.Parse(pi)\n\tif err != nil {\n\t\treturn r, true, err\n\t}\n\tif !ok {\n\t\terr = parse.Error(fmt.Sprintf(\"<%s>: expected end tag not present or invalid tag contents\", r.Name), pi.Position())\n\t\treturn r, true, err\n\t}\n\n\treturn addTrailingSpaceAndValidate(start, r, pi)\n}\n\nfunc addTrailingSpaceAndValidate(start parse.Position, e *Element, pi *parse.Input) (n Node, ok bool, err error) {\n\t// Elide any void close tags.\n\tif _, _, err = voidElementCloser.Parse(pi); err != nil {\n\t\treturn e, false, err\n\t}\n\t// Add trailing space.\n\tws, _, err := parse.Whitespace.Parse(pi)\n\tif err != nil {\n\t\treturn e, false, err\n\t}\n\te.TrailingSpace, err = NewTrailingSpace(ws)\n\tif err != nil {\n\t\treturn e, false, err\n\t}\n\n\t// Validate.\n\tvar msgs []string\n\tif msgs, ok = e.Validate(); !ok {\n\t\terr = parse.Error(fmt.Sprintf(\"<%s>: %s\", e.Name, strings.Join(msgs, \", \")), start)\n\t\treturn e, false, err\n\t}\n\n\te.Range = NewRange(start, pi.Position())\n\treturn e, true, nil\n}\n"
  },
  {
    "path": "parser/v2/elementparser_test.go",
    "content": "package parser\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\ntype attributeTest[T any] struct {\n\tname     string\n\tinput    string\n\tparser   parse.Parser[T]\n\texpected T\n}\n\nfunc TestAttributeParser(t *testing.T) {\n\ttests := []attributeTest[any]{\n\t\t{\n\t\t\tname:   \"element: open\",\n\t\t\tinput:  `<a>`,\n\t\t\tparser: StripType(elementOpenTagParser),\n\t\t\texpected: elementOpenTag{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"element: hyphen in name\",\n\t\t\tinput:  `<turbo-frame>`,\n\t\t\tparser: StripType(elementOpenTagParser),\n\t\t\texpected: elementOpenTag{\n\t\t\t\tName: \"turbo-frame\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"element: open with hyperscript attribute\",\n\t\t\tinput:  `<div _=\"show = true\">`,\n\t\t\tparser: StripType(elementOpenTagParser),\n\t\t\texpected: elementOpenTag{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"show = true\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"_\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"element: open with complex attributes\",\n\t\t\tinput:  `<div @click=\"show = true\" :class=\"{'foo': true}\">`,\n\t\t\tparser: StripType(elementOpenTagParser),\n\t\t\texpected: elementOpenTag{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"show = true\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"@click\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 25, Line: 0, Col: 25},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"{'foo': true}\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \":class\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 26, Line: 0, Col: 26},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 32, Line: 0, Col: 32},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 26, Line: 0, Col: 26},\n\t\t\t\t\t\t\tTo:   Position{Index: 48, Line: 0, Col: 48},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"element: open with attributes\",\n\t\t\tinput:  `<div id=\"123\" style=\"padding: 10px\">`,\n\t\t\tparser: StripType(elementOpenTagParser),\n\t\t\texpected: elementOpenTag{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"123\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"id\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 13, Line: 0, Col: 13},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"padding: 10px\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 19, Line: 0, Col: 19},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t\t\t\tTo:   Position{Index: 35, Line: 0, Col: 35},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"conditional expression attribute - single\",\n\t\t\tinput: `\n\t\tif p.important {\n\t\t\tclass=\"important\"\n\t\t}\n\"`,\n\t\t\tparser: StripType(conditionalAttribute),\n\t\t\texpected: &ConditionalAttribute{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"p.important\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 17,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"important\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 23, Line: 2, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 28, Line: 2, Col: 8},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 23, Line: 2, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 40, Line: 2, Col: 20},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 3, Line: 1, Col: 2},\n\t\t\t\t\tTo:   Position{Index: 44, Line: 3, Col: 3},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"conditional expression attribute - multiple\",\n\t\t\tinput: `\nif test {` + \" \" + `\n\tclass=\"itIsTrue\"\n\tnoshade\n\tname={ \"other\" }\n}\n\"`,\n\t\t\tparser: StripType(conditionalAttribute),\n\t\t\texpected: &ConditionalAttribute{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"test\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 8,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"itIsTrue\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 2, Col: 1},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 18, Line: 2, Col: 6},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 2, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 29, Line: 2, Col: 17},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 31, Line: 3, Col: 1},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 38, Line: 3, Col: 8},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 31, Line: 3, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 38, Line: 3, Col: 8},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"name\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 40, Line: 4, Col: 1},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 44, Line: 4, Col: 5},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"other\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 47,\n\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 54,\n\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 1, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 58, Line: 5, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"boolean expression attribute\",\n\t\t\tinput:  ` noshade?={ true }\"`,\n\t\t\tparser: StripType(boolExpressionAttributeParser),\n\t\t\texpected: &BoolExpressionAttribute{\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"true\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 18, Line: 0, Col: 18},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"boolean expression attribute without spaces\",\n\t\t\tinput:  ` noshade?={true}\"`,\n\t\t\tparser: StripType(boolExpressionAttributeParser),\n\t\t\texpected: &BoolExpressionAttribute{\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"true\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 16, Line: 0, Col: 16},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"attribute parsing handles boolean expression attributes\",\n\t\t\tinput:  ` noshade?={ true }`,\n\t\t\tparser: StripType(attributeParser{}),\n\t\t\texpected: &BoolExpressionAttribute{\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"true\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 18, Line: 0, Col: 18},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"boolean expression with excess spaces\",\n\t\t\tinput:  ` noshade?={ true   }\"`,\n\t\t\tparser: StripType(boolExpressionAttributeParser),\n\t\t\texpected: &BoolExpressionAttribute{\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"true\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"spread attributes\",\n\t\t\tinput:  ` { spread... }\"`,\n\t\t\tparser: StripType(spreadAttributesParser),\n\t\t\texpected: &SpreadAttributes{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"spread\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   9,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"constant attribute\",\n\t\t\tinput:  ` href=\"test\"`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue: \"test\",\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"href\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"single quote not required constant attribute\",\n\t\t\tinput:  ` href='no double quote in value'`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue:       `no double quote in value`,\n\t\t\t\tSingleQuote: false,\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"href\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 32, Line: 0, Col: 32},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"single quote required constant attribute\",\n\t\t\tinput:  ` href='\"test\"'`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue:       `\"test\"`,\n\t\t\t\tSingleQuote: true,\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"href\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"attribute name with hyphens\",\n\t\t\tinput:  ` data-turbo-permanent=\"value\"`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue: \"value\",\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"data-turbo-permanent\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 29, Line: 0, Col: 29},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"empty attribute\",\n\t\t\tinput:  ` data=\"\"`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue: \"\",\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"data\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiline attribute\",\n\t\t\tinput: ` data-script=\"on click\n                do something\n             end\"\n`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue: \"on click\\n                do something\\n             end\",\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"data-script\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 69, Line: 2, Col: 17},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"bool constant attribute\",\n\t\t\tinput:  `<div data>`,\n\t\t\tparser: StripType(elementOpenTagParser),\n\t\t\texpected: elementOpenTag{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"data\",\n\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"bool constant attribute with expression key\",\n\t\t\tinput:  `<div { \"foo\" }>`,\n\t\t\tparser: StripType(elementOpenTagParser),\n\t\t\texpected: elementOpenTag{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ExpressionAttributeKey{\n\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\tValue: `\"foo\"`,\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"bool constant attributes can end with a Unix newline\",\n\t\t\tinput:  \"<input\\n\\t\\trequired\\n\\t/>\",\n\t\t\tparser: StripType(element),\n\t\t\texpected: &Element{\n\t\t\t\tName:        \"input\",\n\t\t\t\tIndentAttrs: true,\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"required\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 9, Line: 1, Col: 2},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 17, Line: 1, Col: 10},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 9, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 17, Line: 1, Col: 10},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 21, Line: 2, Col: 3},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"bool constant attributes can end with a Windows newline\",\n\t\t\tinput:  \"<input\\r\\n\\t\\trequired\\r\\n\\t/>\",\n\t\t\tparser: StripType(element),\n\t\t\texpected: &Element{\n\t\t\t\tName:        \"input\",\n\t\t\t\tIndentAttrs: true,\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"required\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 10, Line: 1, Col: 2},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 18, Line: 1, Col: 10},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 10, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 18, Line: 1, Col: 10},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 23, Line: 2, Col: 3},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"constant attribute values are parsed as-is (single quoted)\",\n\t\t\tinput:  ` href='\"'`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue:       `\"`,\n\t\t\t\tSingleQuote: true,\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"href\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"constant attribute values are parsed as-is (double quoted)\",\n\t\t\tinput:  ` href=\"&lt;'\"`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue: `&lt;'`,\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"href\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 13, Line: 0, Col: 13},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"htmx wildcard attribute names are supported\",\n\t\t\tinput:  ` hx-target-*=\"#errors\"`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue: `#errors`,\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"hx-target-*\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 22, Line: 0, Col: 22},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"unquoted attributes are supported\",\n\t\t\tinput:  ` data=123`,\n\t\t\tparser: StripType(constantAttributeParser),\n\t\t\texpected: &ConstantAttribute{\n\t\t\t\tValue: \"123\",\n\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\tName: \"data\",\n\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, matched, err := tt.parser.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Errorf(\"failed to parse at %v\", input.Position())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestVoidElementCloserParser(t *testing.T) {\n\tt.Run(\"all void elements are parsed\", func(t *testing.T) {\n\t\tfor _, input := range voidElementCloseTags {\n\t\t\t_, matched, err := voidElementCloser.Parse(parse.NewInput(input))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"failed to parse %q\", input)\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestElementParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *Element\n\t}{\n\t\t{\n\t\t\tname:  \"element: self-closing with single constant attribute\",\n\t\t\tinput: `<a href=\"test\"/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"test\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"href\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 16, Line: 0, Col: 16},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: colon in name, empty\",\n\t\t\tinput: `<maps:map></maps:map>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"maps:map\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: colon in name, with content\",\n\t\t\tinput: `<maps:map>Content</maps:map>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"maps:map\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tValue: \"Content\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 10, Line: 0, Col: 10},\n\t\t\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 28, Line: 0, Col: 28},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: void (input)\",\n\t\t\tinput: `<input>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"input\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\tChildren: nil,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: void (br)\",\n\t\t\tinput: `<br>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"br\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tChildren: nil,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: void (hr)\",\n\t\t\tinput: `<hr noshade>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: nil,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: void with content\",\n\t\t\tinput: `<input>Text</input>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"input\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\t// <input> is a void element, so text is not a child of the input.\n\t\t\t\t// </input> is ignored.\n\t\t\t\tChildren: nil,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with single bool expression attribute\",\n\t\t\tinput: `<hr noshade?={ true }/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&BoolExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `true`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 19,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   19,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 23, Line: 0, Col: 23},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: void nesting same is OK\",\n\t\t\tinput: `<div><br><br></br></div>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"br\", // The <br> one.\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\t\tTo:   Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"br\", // The <br></br> one.\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 10, Line: 0, Col: 10},\n\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t\t\tTo:   Position{Index: 18, Line: 0, Col: 18},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 24, Line: 0, Col: 24},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: void nesting is ignored\",\n\t\t\tinput: `<br><hr></br>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"br\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\t// <br> is a void element, so <hr> is not a child of the <br>.\n\t\t\t\t// </br> is ignored.\n\t\t\t\tChildren: nil,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with single expression attribute\",\n\t\t\tinput: `<a href={ \"test\" }/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"href\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"test\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with multiple constant attributes\",\n\t\t\tinput: `<a href=\"test\" style=\"text-underline: auto\"/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"test\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"href\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"text-underline: auto\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t\t\t\tTo:   Position{Index: 43, Line: 0, Col: 43},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 45, Line: 0, Col: 45},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with multiple spreads attributes\",\n\t\t\tinput: `<a { firstSpread... } { children... }/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&SpreadAttributes{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"firstSpread\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 5,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&SpreadAttributes{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"children\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 24,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   24,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   32,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 22, Line: 0, Col: 22},\n\t\t\t\t\t\t\tTo:   Position{Index: 37, Line: 0, Col: 37},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 39, Line: 0, Col: 39},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with multiple boolean attributes\",\n\t\t\tinput: `<hr optionA optionB?={ true } optionC=\"other\"/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"optionA\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&BoolExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"optionB\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 19, Line: 0, Col: 19},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `true`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   27,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t\tTo:   Position{Index: 29, Line: 0, Col: 29},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"other\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"optionC\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 30, Line: 0, Col: 30},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 37, Line: 0, Col: 37},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 30, Line: 0, Col: 30},\n\t\t\t\t\t\t\tTo:   Position{Index: 45, Line: 0, Col: 45},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 47, Line: 0, Col: 47},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with multiple constant and expr attributes\",\n\t\t\tinput: `<a href=\"test\" title={ localisation.Get(\"a_title\") } style=\"text-underline: auto\"/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"test\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"href\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"title\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `localisation.Get(\"a_title\")`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 50,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   50,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"text-underline: auto\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 53, Line: 0, Col: 53},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 58, Line: 0, Col: 58},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 53, Line: 0, Col: 53},\n\t\t\t\t\t\t\tTo:   Position{Index: 81, Line: 0, Col: 81},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 83, Line: 0, Col: 83},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"element: self-closing with multiple constant, conditional and expr attributes\",\n\t\t\tinput: `<div style=\"width: 100;\"\n\t\tif p.important {\n\t\t\tclass=\"important\"\n\t\t}\n>Test</div>\n}\n\n`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"width: 100;\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 10, Line: 0, Col: 10},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 24, Line: 0, Col: 24},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConditionalAttribute{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.important`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 41,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"important\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 47, Line: 2, Col: 3},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 52, Line: 2, Col: 8},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 47, Line: 2, Col: 3},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 64, Line: 2, Col: 20},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 27, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 68, Line: 3, Col: 3},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tIndentAttrs: true,\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tValue: \"Test\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 70, Line: 4, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 74, Line: 4, Col: 5},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 81, Line: 5, Col: 0},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with no attributes\",\n\t\t\tinput: `<hr/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with attribute\",\n\t\t\tinput: `<hr style=\"padding: 10px\" />`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"padding: 10px\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 25, Line: 0, Col: 25},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 28, Line: 0, Col: 28},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"element: self-closing with conditional attribute\",\n\t\t\tinput: `<hr style=\"padding: 10px\"` + \" \" + `\n\t\t\tif true {\n\t\t\t\tclass=\"itIsTrue\"\n\t\t\t}\n/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"padding: 10px\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 25, Line: 0, Col: 25},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConditionalAttribute{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"true\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 33,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 37,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"itIsTrue\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 44, Line: 2, Col: 4},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 49, Line: 2, Col: 9},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 44, Line: 2, Col: 4},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 60, Line: 2, Col: 20},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 30, Line: 1, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 65, Line: 3, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tIndentAttrs: true,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 68, Line: 4, Col: 2},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"element: self-closing with conditional attribute with else block\",\n\t\t\tinput: `<hr style=\"padding: 10px\"` + \" \" + `\n\t\t\tif true {\n\t\t\t\tclass=\"itIsTrue\"\n\t\t\t} else {\n\t\t\t\tclass=\"itIsNotTrue\"\n\t\t\t}\n/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"padding: 10px\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 25, Line: 0, Col: 25},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConditionalAttribute{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"true\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 33,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 37,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"itIsTrue\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 44, Line: 2, Col: 4},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 49, Line: 2, Col: 9},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 44, Line: 2, Col: 4},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 60, Line: 2, Col: 20},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tElse: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"itIsNotTrue\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 77, Line: 4, Col: 4},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 82, Line: 4, Col: 9},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 77, Line: 4, Col: 4},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 96, Line: 4, Col: 23},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 30, Line: 1, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 101, Line: 5, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tIndentAttrs: true,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 104, Line: 6, Col: 2},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"element: open and close with conditional attribute\",\n\t\t\tinput: `<p style=\"padding: 10px\"` + \" \" + `\n\t\t\tif true {\n\t\t\t\tclass=\"itIsTrue\"\n\t\t\t}\n>Test</p>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"p\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"padding: 10px\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"style\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 24, Line: 0, Col: 24},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConditionalAttribute{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"true\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 36,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"itIsTrue\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 43, Line: 2, Col: 4},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 48, Line: 2, Col: 9},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 43, Line: 2, Col: 4},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 59, Line: 2, Col: 20},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 29, Line: 1, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 64, Line: 3, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tIndentAttrs: true,\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tValue: \"Test\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 66, Line: 4, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 70, Line: 4, Col: 5},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 74, Line: 4, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: open and close\",\n\t\t\tinput: `<a></a>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: open and close with text\",\n\t\t\tinput: `<a>The text</a>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tValue: \"The text\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: with self-closing child element\",\n\t\t\tinput: `<a><b/></a>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"b\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: with non-self-closing child element\",\n\t\t\tinput: `<a><b></b></a>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"b\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 10, Line: 0, Col: 10},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: containing space\",\n\t\t\tinput: `<a> <b> </b> </a>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \" \"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"b\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 8,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \" \"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceHorizontal,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 13, Line: 0, Col: 13},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: with multiple child elements\",\n\t\t\tinput: `<a><b></b><c><d/></c></a>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"a\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 2, Line: 0, Col: 2},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"b\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 10, Line: 0, Col: 10},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"c\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Element{\n\t\t\t\t\t\t\t\tName: \"d\",\n\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 0, Col: 13},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 10, Line: 0, Col: 10},\n\t\t\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 25, Line: 0, Col: 25},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: empty\",\n\t\t\tinput: `<div></div>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: containing string expression\",\n\t\t\tinput: `<div>{ \"test\" }</div>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"test\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 13,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   13,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: inputs can contain class attributes\",\n\t\t\tinput: `<input  type=\"email\" id=\"email\" name=\"email\" class={ \"a\", \"b\", \"c\",  templ.KV(\"c\", false)}\tplaceholder=\"your@email.com\" autocomplete=\"off\"/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"input\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"email\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"type\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"email\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"id\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 23, Line: 0, Col: 23},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t\t\t\tTo:   Position{Index: 31, Line: 0, Col: 31},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"email\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"name\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 32, Line: 0, Col: 32},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 36, Line: 0, Col: 36},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 32, Line: 0, Col: 32},\n\t\t\t\t\t\t\tTo:   Position{Index: 44, Line: 0, Col: 44},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"class\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 45, Line: 0, Col: 45},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 50, Line: 0, Col: 50},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"a\", \"b\", \"c\",  templ.KV(\"c\", false)`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 53,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   53,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 89,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   89,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"your@email.com\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"placeholder\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 91, Line: 0, Col: 91},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 102, Line: 0, Col: 102},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 91, Line: 0, Col: 91},\n\t\t\t\t\t\t\tTo:   Position{Index: 119, Line: 0, Col: 119},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"off\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"autocomplete\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 120, Line: 0, Col: 120},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 132, Line: 0, Col: 132},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 120, Line: 0, Col: 120},\n\t\t\t\t\t\t\tTo:   Position{Index: 138, Line: 0, Col: 138},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 140, Line: 0, Col: 140},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"element: with multi-line attributes\",\n\t\t\tinput: `<input\n\ttype=\"email\"` + \" \" + `\n\tid=\"email\"` + \" \" + `\n\tname=\"email\"\n></input>`,\n\t\t\texpected: &Element{\n\t\t\t\tName:        \"input\",\n\t\t\t\tIndentAttrs: true,\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"email\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"type\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 1, Col: 1},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 1, Col: 5},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 1, Col: 13},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"email\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"id\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 23, Line: 2, Col: 1},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 25, Line: 2, Col: 3},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 23, Line: 2, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 33, Line: 2, Col: 11},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"email\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"name\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 36, Line: 3, Col: 1},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 40, Line: 3, Col: 5},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 36, Line: 3, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 48, Line: 3, Col: 13},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 58, Line: 4, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with unquoted attribute\",\n\t\t\tinput: `<hr noshade=noshade/>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"noshade\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: self-closing with unquoted and other attributes\",\n\t\t\tinput: `<hr noshade=noshade disabled other-attribute={ false } />`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"hr\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"noshade\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"noshade\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&BoolConstantAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"disabled\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 28, Line: 0, Col: 28},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t\tTo:   Position{Index: 28, Line: 0, Col: 28},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&ExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"other-attribute\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 29, Line: 0, Col: 29},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 44, Line: 0, Col: 44},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"false\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 47,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   47,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 52,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   52,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 57, Line: 0, Col: 57},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"element: space before name= { is still parsed as an expression\",\n\t\t\tinput: `<div hx-vals= { \"test\" }></div>`,\n\t\t\texpected: &Element{\n\t\t\t\tName: \"div\",\n\t\t\t\tNameRange: Range{\n\t\t\t\t\tFrom: Position{Index: 1, Line: 0, Col: 1},\n\t\t\t\t\tTo:   Position{Index: 4, Line: 0, Col: 4},\n\t\t\t\t},\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ExpressionAttribute{\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"hx-vals\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 5, Line: 0, Col: 5},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"test\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 22,\n\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\tCol:   22,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 31, Line: 0, Col: 31},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, matched, err := element.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestElementParserErrors(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected error\n\t}{\n\t\t{\n\t\t\tname:  \"element: mismatched end tag\",\n\t\t\tinput: `<a></b>`,\n\t\t\texpected: parse.Error(\"<a>: close tag not found\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 3,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   3,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tname:  \"element: style must only contain text\",\n\t\t\tinput: `<style><button /></style>`,\n\t\t\texpected: parse.Error(\"<style>: invalid node contents: style elements must only contain text\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 0,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   0,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tname:  \"element: style tags cannot contain non-text nodes\",\n\t\t\tinput: `<style>{ \"value\" }</style>`,\n\t\t\texpected: parse.Error(\"<style>: invalid node contents: style elements must only contain text\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 0,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   0,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tname:  \"element: names cannot be greater than 128 characters\",\n\t\t\tinput: `<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa></aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>`,\n\t\t\texpected: parse.Error(\"element names must be < 128 characters long\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 130,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   130,\n\t\t\t\t}),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, _, err := element.Parse(input)\n\t\t\tif diff := cmp.Diff(tt.expected, err); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBigElement(t *testing.T) {\n\tsb := new(strings.Builder)\n\tsb.WriteString(\"<div>\")\n\tsb.WriteString(strings.Repeat(\"a\", 16384))\n\tsb.WriteString(\"</div>\")\n\t_, matched, err := element.Parse(parse.NewInput(sb.String()))\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\tif !matched {\n\t\tt.Errorf(\"unexpected failure to parse\")\n\t}\n}\n\nfunc FuzzElement(f *testing.F) {\n\tseeds := []string{\n\t\t`<br>`,\n\t\t`<a href=\"test\" unquoted=unquoted/>`,\n\t\t`<input value={ \"test\" }/>`,\n\t\t`<div>{ \"test\" }</div>`,\n\t\t`<a unquoted=unquoted href=\"test\" unquoted=unquoted>Test</a>`,\n\t}\n\n\tfor _, tc := range seeds {\n\t\tf.Add(tc)\n\t}\n\n\tf.Fuzz(func(t *testing.T, input string) {\n\t\t_, _, _ = element.Parse(parse.NewInput(input))\n\t})\n}\n\nfunc TestElementFormatting(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"element can be formatted\",\n\t\t\tinput:    `<div>Text</div>`,\n\t\t\texpected: `<div>Text</div>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"attribute escaping is not lost\",\n\t\t\tinput:    `<div data-line-data=\"[{&quot;x&quot;: 0, &quot;y&quot;: 1 }]\"></div>`,\n\t\t\texpected: `<div data-line-data=\"[{&quot;x&quot;: 0, &quot;y&quot;: 1 }]\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"constant attributes are not re-escaped - single quote\",\n\t\t\tinput:    `<div data-line-data='\"'></div>`,\n\t\t\texpected: `<div data-line-data='\"'></div>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"constant attributes are not re-escaped - double quote\",\n\t\t\tinput:    `<div data-line-data='\"'></div>`,\n\t\t\texpected: `<div data-line-data='\"'></div>`,\n\t\t},\n\t\t{\n\t\t\tname:  \"constant attributes are not re-escaped - backslash\",\n\t\t\tinput: `<div data-line-data='\\'></div>`,\n\t\t\t// templ formatting prefers double quotes.\n\t\t\texpected: `<div data-line-data=\"\\\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:  \"constant attributes are not re-escaped - ampersand\",\n\t\t\tinput: `<div data-line-data='&'></div>`,\n\t\t\t// templ formatting prefers double quotes.\n\t\t\texpected: `<div data-line-data=\"&\"></div>`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, matched, err := element.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tformatted := new(strings.Builder)\n\t\t\tif err = result.Write(formatted, 0); err != nil {\n\t\t\t\tt.Fatalf(\"failed to format: %v\", err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, formatted.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/expressionparser.go",
    "content": "package parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/a-h/parse\"\n)\n\n// StripType takes the parser and throws away the return value.\nfunc StripType[T any](p parse.Parser[T]) parse.Parser[any] {\n\treturn parse.Func(func(in *parse.Input) (out any, matched bool, err error) {\n\t\treturn p.Parse(in)\n\t})\n}\n\nfunc ExpressionOf(p parse.Parser[string]) parse.Parser[Expression] {\n\treturn parse.Func(func(in *parse.Input) (out Expression, matched bool, err error) {\n\t\tfrom := in.Position()\n\n\t\tvar exp string\n\t\tif exp, matched, err = p.Parse(in); err != nil || !matched {\n\t\t\treturn\n\t\t}\n\n\t\treturn NewExpression(exp, from, in.Position()), true, nil\n\t})\n}\n\nvar lt = parse.Rune('<')\nvar gt = parse.Rune('>')\nvar spaceOrTab = parse.Any(parse.Rune(' '), parse.Rune('\\t'))\nvar spaceOrTabOrNewLine = parse.Any(spaceOrTab, parse.String(\"\\r\\n\"), parse.Rune('\\n'))\nvar openBrace = parse.String(\"{\")\nvar optionalSpaces = parse.StringFrom(parse.Optional(\n\tparse.AtLeast(1, spaceOrTab)))\nvar optionalSpacesOrNewLine = parse.StringFrom(parse.Optional(\n\tparse.AtLeast(1, spaceOrTabOrNewLine)))\nvar openBraceWithPadding = parse.StringFrom(optionalSpaces,\n\topenBrace,\n\toptionalSpaces)\nvar openBraceWithOptionalPadding = parse.Any(openBraceWithPadding, openBrace)\n\nvar closeBrace = parse.String(\"}\")\nvar closeBraceWithOptionalPadding = parse.StringFrom(optionalSpaces, closeBrace)\n\nvar dblOpenBrace = parse.String(\"{{\")\nvar dblOpenBraceWithOptionalPaddingOrNewLine = parse.StringFrom(dblOpenBrace, optionalSpacesOrNewLine)\n\nvar dblCloseBrace = parse.String(\"}}\")\nvar dblCloseBraceWithOptionalPadding = parse.StringFrom(optionalSpaces, dblCloseBrace)\n\nvar openBracket = parse.String(\"(\")\nvar closeBracket = parse.String(\")\")\n\nvar stringUntilNewLine = parse.StringUntil(parse.NewLine)\nvar newLineOrEOF = parse.Or(parse.NewLine, parse.EOF[string]())\nvar stringUntilNewLineOrEOF = parse.StringUntil(newLineOrEOF)\n\nvar jsOrGoSingleLineComment = parse.StringFrom(parse.String(\"//\"), parse.StringUntil(parse.Any(parse.NewLine, parse.EOF[string]())))\nvar jsOrGoMultiLineComment = parse.StringFrom(parse.String(\"/*\"), parse.StringUntil(parse.String(\"*/\")))\n\nvar exp = expressionParser{\n\tstartBraceCount: 1,\n}\n\ntype expressionParser struct {\n\tstartBraceCount int\n}\n\nfunc (p expressionParser) Parse(pi *parse.Input) (s Expression, matched bool, err error) {\n\tfrom := pi.Position()\n\n\tbraceCount := p.startBraceCount\n\n\tsb := new(strings.Builder)\nloop:\n\tfor {\n\t\tvar result string\n\n\t\t// Try to parse a single line comment.\n\t\tif result, matched, err = jsOrGoSingleLineComment.Parse(pi); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif matched {\n\t\t\tsb.WriteString(result)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Try to parse a multi-line comment.\n\t\tif result, matched, err = jsOrGoMultiLineComment.Parse(pi); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif matched {\n\t\t\tsb.WriteString(result)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Try to read a string literal.\n\t\tif result, matched, err = string_lit.Parse(pi); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif matched {\n\t\t\tsb.WriteString(result)\n\t\t\tcontinue\n\t\t}\n\t\t// Also try for a rune literal.\n\t\tif result, matched, err = rune_lit.Parse(pi); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif matched {\n\t\t\tsb.WriteString(result)\n\t\t\tcontinue\n\t\t}\n\t\t// Try opener.\n\t\tif result, matched, err = openBrace.Parse(pi); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif matched {\n\t\t\tbraceCount++\n\t\t\tsb.WriteString(result)\n\t\t\tcontinue\n\t\t}\n\t\t// Try closer.\n\t\tstartOfCloseBrace := pi.Index()\n\t\tif result, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif matched {\n\t\t\tbraceCount--\n\t\t\tif braceCount < 0 {\n\t\t\t\terr = parse.Error(\"expression: too many closing braces\", pi.Position())\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif braceCount == 0 {\n\t\t\t\tpi.Seek(startOfCloseBrace)\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tsb.WriteString(result)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Read anything else.\n\t\tvar c string\n\t\tc, matched = pi.Take(1)\n\t\tif !matched {\n\t\t\tbreak loop\n\t\t}\n\t\tif rune(c[0]) == 65533 { // Invalid Unicode.\n\t\t\tbreak loop\n\t\t}\n\t\tsb.WriteString(c)\n\t}\n\tif braceCount != 0 {\n\t\terr = parse.Error(\"expression: unexpected brace count\", pi.Position())\n\t\treturn\n\t}\n\n\treturn NewExpression(sb.String(), from, pi.Position()), true, nil\n}\n\n// Letters and digits\n\nvar octal_digit = parse.RuneIn(\"01234567\")\nvar hex_digit = parse.RuneIn(\"0123456789ABCDEFabcdef\")\n\n// https://go.dev/ref/spec#Rune_literals\n\nvar rune_lit = parse.StringFrom(\n\tparse.Rune('\\''),\n\tparse.StringFrom(parse.Until(\n\t\tparse.Any(unicode_value_rune, byte_value),\n\t\tparse.Rune('\\''),\n\t)),\n\tparse.Rune('\\''),\n)\nvar unicode_value_rune = parse.Any(little_u_value, big_u_value, escaped_char, parse.RuneNotIn(\"'\"))\n\n// byte_value       = octal_byte_value | hex_byte_value .\nvar byte_value = parse.Any(octal_byte_value, hex_byte_value)\n\n// octal_byte_value = `\\` octal_digit octal_digit octal_digit .\nvar octal_byte_value = parse.StringFrom(\n\tparse.String(`\\`),\n\toctal_digit, octal_digit, octal_digit,\n)\n\n// hex_byte_value   = `\\` \"x\" hex_digit hex_digit .\nvar hex_byte_value = parse.StringFrom(\n\tparse.String(`\\x`),\n\thex_digit, hex_digit,\n)\n\n// little_u_value   = `\\` \"u\" hex_digit hex_digit hex_digit hex_digit .\nvar little_u_value = parse.StringFrom(\n\tparse.String(`\\u`),\n\thex_digit, hex_digit,\n\thex_digit, hex_digit,\n)\n\n// big_u_value      = `\\` \"U\" hex_digit hex_digit hex_digit hex_digit\nvar big_u_value = parse.StringFrom(\n\tparse.String(`\\U`),\n\thex_digit, hex_digit, hex_digit, hex_digit,\n\thex_digit, hex_digit, hex_digit, hex_digit,\n)\n\n// escaped_char     = `\\` ( \"a\" | \"b\" | \"f\" | \"n\" | \"r\" | \"t\" | \"v\" | `\\` | \"'\" | `\"` ) .\nvar escaped_char = parse.StringFrom(\n\tparse.Rune('\\\\'),\n\tparse.Any(\n\t\tparse.Rune('a'),\n\t\tparse.Rune('b'),\n\t\tparse.Rune('f'),\n\t\tparse.Rune('n'),\n\t\tparse.Rune('r'),\n\t\tparse.Rune('t'),\n\t\tparse.Rune('v'),\n\t\tparse.Rune('\\\\'),\n\t\tparse.Rune('\\''),\n\t\tparse.Rune('\"'),\n\t),\n)\n\n// https://go.dev/ref/spec#String_literals\n\nvar string_lit = parse.Any(parse.String(`\"\"`), parse.String(`''`), interpreted_string_lit, raw_string_lit)\n\nvar interpreted_string_lit = parse.StringFrom(\n\tparse.Rune('\"'),\n\tparse.StringFrom(parse.Until(\n\t\tparse.Any(unicode_value_interpreted, byte_value),\n\t\tparse.Rune('\"'),\n\t)),\n\tparse.Rune('\"'),\n)\nvar unicode_value_interpreted = parse.Any(little_u_value, big_u_value, escaped_char, parse.RuneNotIn(\"\\n\\\"\"))\n\nvar raw_string_lit = parse.StringFrom(\n\tparse.Rune('`'),\n\tparse.StringFrom(parse.Until(\n\t\tunicode_value_raw,\n\t\tparse.Rune('`'),\n\t)),\n\tparse.Rune('`'),\n)\nvar unicode_value_raw = parse.Any(little_u_value, big_u_value, escaped_char, parse.RuneNotIn(\"`\"))\n"
  },
  {
    "path": "parser/v2/expressionparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\n// # List of situations where a templ file could contain braces.\n\n// Inside a HTML attribute.\n// <a style=\"font-family: { arial }\">That does not make sense, but still...</a>\n\n// Inside a script tag.\n// <script>var value = { test: 123 };</script>\n\n// Inside a templ definition expression.\n// { templ Name(data map[string]any) }\n\n// Inside a templ script.\n// { script Name(data map[string]any) }\n//   { something }\n// { endscript }\n\n// Inside a call to a template, passing some data.\n// {! localisations(map[string]any { \"key\": 123 }) }\n\n// Inside a string.\n// {! localisations(\"\\\"value{'data'}\") }\n\n// Inside a tick string.\n// {! localisations(`value{'data'}`) }\n\n// Parser logic...\n// Read until ( ` | \" | { | } | EOL/EOF )\n//  If \" handle any escaped quotes or ticks until the end of the string.\n//  If ` read until the closing tick.\n//  If { increment the brace count up\n//  If } increment the brace count down\n//    If brace count == 0, break\n//  If EOL, break\n//  If EOF, break\n// If brace count != 0 throw an error\n\nfunc TestRuneLiterals(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"rune literal with escaped newline\",\n\t\t\tinput:    `'\\n' `,\n\t\t\texpected: `'\\n'`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tactual, ok, err := rune_lit.Parse(parse.NewInput(tt.input))\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestStringLiterals(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"string literal with escaped newline\",\n\t\t\tinput:    `\"\\n\" `,\n\t\t\texpected: `\"\\n\"`,\n\t\t},\n\t\t{\n\t\t\tname:     \"raw literal with \\n\",\n\t\t\tinput:    \"`\\\\n` \",\n\t\t\texpected: \"`\\\\n`\",\n\t\t},\n\t\t{\n\t\t\tname:     \"empty single quote string\",\n\t\t\tinput:    `'' `,\n\t\t\texpected: `''`,\n\t\t},\n\t\t{\n\t\t\tname:     \"empty double quote string\",\n\t\t\tinput:    `\"\" `,\n\t\t\texpected: `\"\"`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tactual, ok, err := string_lit.Parse(parse.NewInput(tt.input))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestExpressions(t *testing.T) {\n\ttests := []struct {\n\t\tname            string\n\t\tinput           string\n\t\tprefix          string\n\t\tstartBraceCount int\n\t\texpected        string\n\t}{\n\t\t{\n\t\t\tname:            \"templ: no parameters\",\n\t\t\tinput:           \"{ templ TemplName() }\\n\",\n\t\t\tprefix:          \"{ templ \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        \"TemplName()\",\n\t\t},\n\t\t{\n\t\t\tname:            \"templ: string parameter\",\n\t\t\tinput:           `{ templ TemplName(a string) }`,\n\t\t\tprefix:          \"{ templ \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `TemplName(a string)`,\n\t\t},\n\t\t{\n\t\t\tname:            \"templ: map parameter\",\n\t\t\tinput:           `{ templ TemplName(data map[string]any) }`,\n\t\t\tprefix:          \"{ templ \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `TemplName(data map[string]any)`,\n\t\t},\n\t\t{\n\t\t\tname:            \"call: string parameter\",\n\t\t\tinput:           `{! Header(\"test\") }`,\n\t\t\tprefix:          \"{! \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `Header(\"test\")`,\n\t\t},\n\t\t{\n\t\t\tname:            \"call: string parameter with escaped values and mismatched braces\",\n\t\t\tinput:           `{! Header(\"\\\"}}\") }`,\n\t\t\tprefix:          \"{! \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `Header(\"\\\"}}\")`,\n\t\t},\n\t\t{\n\t\t\tname:            \"call: string parameter, with rune literals\",\n\t\t\tinput:           `{! Header('\\\"') }`,\n\t\t\tprefix:          \"{! \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `Header('\\\"')`,\n\t\t},\n\t\t{\n\t\t\tname:            \"call: map literal\",\n\t\t\tinput:           `{! Header(map[string]any{ \"test\": 123 }) }`,\n\t\t\tprefix:          \"{! \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `Header(map[string]any{ \"test\": 123 })`,\n\t\t},\n\t\t{\n\t\t\tname:            \"call: rune and map literal\",\n\t\t\tinput:           `{! Header('\\\"', map[string]any{ \"test\": 123 }) }`,\n\t\t\tprefix:          \"{! \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `Header('\\\"', map[string]any{ \"test\": 123 })`,\n\t\t},\n\t\t{\n\t\t\tname:            \"if: function call\",\n\t\t\tinput:           `{ if findOut(\"}\") }`,\n\t\t\tprefix:          \"{ if \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `findOut(\"}\")`,\n\t\t},\n\t\t{\n\t\t\tname:            \"if: function call, tricky string/rune params\",\n\t\t\tinput:           `{ if findOut(\"}\", '}', '\\'') }`,\n\t\t\tprefix:          \"{ if \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `findOut(\"}\", '}', '\\'')`,\n\t\t},\n\t\t{\n\t\t\tname:            \"if: function call, function param\",\n\t\t\tinput:           `{ if findOut(func() bool { return true }) }`,\n\t\t\tprefix:          \"{ if \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `findOut(func() bool { return true })`,\n\t\t},\n\t\t{\n\t\t\tname: \"attribute value: simple string\",\n\t\t\t// Used to be {%= \"data\" %}, but can be simplified, since the position\n\t\t\t// of the node in the document defines how it can be used.\n\t\t\t// As an attribute value, it must be a Go expression that returns a string.\n\t\t\tinput:           `{ \"data\" }`,\n\t\t\tprefix:          \"{ \",\n\t\t\tstartBraceCount: 1,\n\t\t\texpected:        `\"data\"`,\n\t\t},\n\t\t{\n\t\t\tname:            \"javascript expression\",\n\t\t\tinput:           \"var x = 123;\",\n\t\t\tprefix:          \"\",\n\t\t\tstartBraceCount: 0,\n\t\t\texpected:        \"var x = 123;\",\n\t\t},\n\t\t{\n\t\t\tname:            \"javascript expression\",\n\t\t\tinput:           `var x = \"}\";`,\n\t\t\tprefix:          \"\",\n\t\t\tstartBraceCount: 0,\n\t\t\texpected:        `var x = \"}\";`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tep := &expressionParser{\n\t\t\t\tstartBraceCount: tt.startBraceCount,\n\t\t\t}\n\t\t\texpr := tt.input[len(tt.prefix):]\n\t\t\tactual, ok, err := ep.Parse(parse.NewInput(expr))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\texpected := Expression{\n\t\t\t\tValue: tt.expected,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{0, 0, 0},\n\t\t\t\t\tTo:   Position{int64(len(tt.expected)), 0, uint32(len(tt.expected))},\n\t\t\t\t},\n\t\t\t}\n\t\t\tif diff := cmp.Diff(expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/fallthroughparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\nvar fallthroughString = parse.String(\"fallthrough\")\n\nvar fallthroughExpression = parse.Func(func(pi *parse.Input) (n Node, ok bool, err error) {\n\tstart := pi.Position()\n\tif _, ok, err = fallthroughString.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Eat terminating newline.\n\t_, _, _ = parse.ZeroOrMore(parse.RuneIn(\" \\t\")).Parse(pi)\n\t_, ok, err = parse.NewLine.Parse(pi)\n\tif err != nil || !ok {\n\t\terr = parse.Error(\"expected newline after fallthrough\", pi.Position())\n\t\treturn nil, true, err\n\t}\n\n\treturn &Fallthrough{\n\t\tRange: NewRange(start, pi.Position()),\n\t}, true, nil\n})\n"
  },
  {
    "path": "parser/v2/fallthroughparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestFallthroughParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *Fallthrough\n\t}{\n\t\t{\n\t\t\tname:  \"basic fallthrough\",\n\t\t\tinput: \"fallthrough\\n\",\n\t\t\texpected: &Fallthrough{\n\t\t\t\tRange: NewRange(parse.Position{Index: 0, Line: 0, Col: 0}, parse.Position{Index: 12, Line: 1, Col: 0}),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"fallthrough with spaces before newline\",\n\t\t\tinput: \"fallthrough    \\n\",\n\t\t\texpected: &Fallthrough{\n\t\t\t\tRange: NewRange(parse.Position{Index: 0, Line: 0, Col: 0}, parse.Position{Index: 16, Line: 1, Col: 0}),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"fallthrough with tabs before newline\",\n\t\t\tinput: \"fallthrough\\t\\t\\t\\n\",\n\t\t\texpected: &Fallthrough{\n\t\t\t\tRange: NewRange(parse.Position{Index: 0, Line: 0, Col: 0}, parse.Position{Index: 15, Line: 1, Col: 0}),\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := fallthroughExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestFallthroughParserErrors(t *testing.T) {\n\tvar tests = []struct {\n\t\tname          string\n\t\tinput         string\n\t\texpectedError error\n\t\texpectedOK    bool\n\t}{\n\t\t{\n\t\t\tname:          \"invalid fallthrough keyword\",\n\t\t\tinput:         `fallthroug`,\n\t\t\texpectedError: nil,\n\t\t\texpectedOK:    false,\n\t\t},\n\t\t{\n\t\t\tname:  \"missing newline after fallthrough\",\n\t\t\tinput: `fallthrough some extra`,\n\t\t\texpectedError: parse.Error(\"expected newline after fallthrough\", parse.Position{\n\t\t\t\tIndex: 12,\n\t\t\t\tLine:  0,\n\t\t\t\tCol:   12,\n\t\t\t}),\n\t\t\texpectedOK: true,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, ok, err := fallthroughExpression.Parse(input)\n\t\t\tif ok != tt.expectedOK {\n\t\t\t\tt.Fatalf(\"expected ok to be %v, got %v\", tt.expectedOK, ok)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expectedError, err); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/forexpressionparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\nvar forExpression parse.Parser[Node] = forExpressionParser{}\n\ntype forExpressionParser struct{}\n\nfunc (forExpressionParser) Parse(pi *parse.Input) (n Node, matched bool, err error) {\n\tr := &ForExpression{}\n\tstart := pi.Index()\n\n\t// Strip leading whitespace and look for `for `.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\treturn r, false, err\n\t}\n\tif !peekPrefix(pi, \"for \") {\n\t\tpi.Seek(start)\n\t\treturn r, false, nil\n\t}\n\n\t// Parse the Go for expression.\n\tif r.Expression, err = parseGo(\"for\", pi, goexpression.For); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Eat \" {\\n\".\n\t_, matched, err = parse.All(openBraceWithOptionalPadding, parse.NewLine).Parse(pi)\n\tif err != nil {\n\t\treturn r, true, err\n\t}\n\tif !matched {\n\t\terr = parse.Error(\"for: \"+unterminatedMissingCurly, pi.PositionAt(start))\n\t\treturn r, true, err\n\t}\n\n\t// Node contents.\n\ttnp := newTemplateNodeParser(closeBraceWithOptionalPadding, \"for expression closing brace\")\n\tvar nodes Nodes\n\tif nodes, matched, err = tnp.Parse(pi); err != nil || !matched {\n\t\t// If we got any nodes, take them, because the LSP might want to use them.\n\t\tr.Children = nodes.Nodes\n\t\treturn r, true, parse.Error(\"for: expected nodes, but none were found\", pi.Position())\n\t}\n\tr.Children = nodes.Nodes\n\n\t// Read the required closing brace.\n\tif _, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !matched {\n\t\treturn r, true, parse.Error(\"for: \"+unterminatedMissingEnd, pi.Position())\n\t}\n\n\tr.Range = NewRange(pi.PositionAt(start), pi.Position())\n\treturn r, true, nil\n}\n"
  },
  {
    "path": "parser/v2/forexpressionparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestForExpressionParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected any\n\t}{\n\t\t{\n\t\t\tname: \"for: infinite\",\n\t\t\tinput: `for {\n\t\t\t\t\tEver\n\t\t\t}`,\n\t\t\texpected: &ForExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\\t\\t\\t\"},\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 11, Line: 1, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 15, Line: 1, Col: 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValue:         \"Ever\",\n\t\t\t\t\t\tTrailingSpace: \"\\n\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 20, Line: 2, Col: 4},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"for: three clause\",\n\t\t\tinput: `for i := 0; i < 10; i ++ {\n\t\t\t\t\tEver\n\t\t\t}`,\n\t\t\texpected: &ForExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"i := 0; i < 10; i ++\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 24,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   24,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\\t\\t\\t\"},\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 32, Line: 1, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 36, Line: 1, Col: 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValue:         \"Ever\",\n\t\t\t\t\t\tTrailingSpace: \"\\n\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 41, Line: 2, Col: 4},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"for: use existing variables\",\n\t\t\tinput: `for x, y = range []int{1, 2} {\n\t\t\t\t\tEver\n\t\t\t}`,\n\t\t\texpected: &ForExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"x, y = range []int{1, 2}\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 28,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   28,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 31,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 36,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\\t\\t\\t\"},\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 36, Line: 1, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 40, Line: 1, Col: 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValue:         \"Ever\",\n\t\t\t\t\t\tTrailingSpace: \"\\n\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 45, Line: 2, Col: 4},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"for: empty first variable\",\n\t\t\tinput: `for _, item := range p.Items {\n\t\t\t\t\t<div>{ item }</div>\n\t\t\t\t}`,\n\t\t\texpected: &ForExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `_, item := range p.Items`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 28,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   28,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 31,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 36,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\\t\\t\\t\"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"div\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 37, Line: 1, Col: 6},\n\t\t\t\t\t\t\tTo:   Position{Index: 40, Line: 1, Col: 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `item`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 43,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 47,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 36, Line: 1, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 60, Line: 2, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 61, Line: 2, Col: 5},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"for: empty first variable, without spaces\",\n\t\t\tinput: `for _, item := range p.Items{\n\t\t\t\t\t<div>{ item }</div>\n\t\t\t\t}`,\n\t\t\texpected: &ForExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `_, item := range p.Items`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 28,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   28,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\\t\\t\\t\"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"div\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 36, Line: 1, Col: 6},\n\t\t\t\t\t\t\tTo:   Position{Index: 39, Line: 1, Col: 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `item`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 42,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 46,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 35, Line: 1, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 59, Line: 2, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 60, Line: 2, Col: 5},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, matched, err := forExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestForExpressionParserNegatives(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\tinput string\n\t}{\n\t\t{\n\t\t\tname:  \"for: wrong case\",\n\t\t\tinput: `For `, // not a for expression\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, matched, err := forExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif matched {\n\t\t\t\tt.Fatal(\"unexpected success\")\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestForExpressionParserIncomplete(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\tinput string\n\t}{\n\t\t{\n\t\t\tname:  \"for: just writing normal text\",\n\t\t\tinput: `for this is`, // not a for expression, use <span>for</span> or `{ \"for\" }` to escape.\n\t\t},\n\t\t{\n\t\t\tname:  \"for: numbers are not variables\",\n\t\t\tinput: `for 1`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: $ is not a variable\",\n\t\t\tinput: `for $`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: bare\",\n\t\t\tinput: `for `,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: infinite\",\n\t\t\tinput: `for {`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: variable i started\",\n\t\t\tinput: `for i`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: variable _ started\",\n\t\t\tinput: `for _`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: variable _ ended with comma\",\n\t\t\tinput: `for _,`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: variable asd ended with comma\",\n\t\t\tinput: `for asd,`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: three clause starting\",\n\t\t\tinput: `for i `,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: three clause starting with assignment\",\n\t\t\tinput: `for i :=`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: three clause starting with initial value\",\n\t\t\tinput: `for i := 0;`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: boolean expression\",\n\t\t\tinput: `for i <`, // 10\n\t\t},\n\t\t{\n\t\t\tname:  \"for: range\",\n\t\t\tinput: `for i := range`,\n\t\t},\n\t\t{\n\t\t\tname:  \"for: k, v\",\n\t\t\tinput: `for k, v`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, matched, err := forExpression.Parse(input)\n\t\t\tif err == nil {\n\t\t\t\tt.Fatal(\"partial for should not be parsed successfully, but got nil\")\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatal(\"expected to be detected as a for loop, but wasn't\")\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/fuzz.sh",
    "content": "#!/bin/bash\necho Element\ngo test -fuzz=FuzzElement -fuzztime=120s\necho Script\ngo test -fuzz=FuzzScript -fuzztime=120s\n"
  },
  {
    "path": "parser/v2/gocodeparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\n// goCode is the parser used to parse Raw Go code within templates.\n//\n// goCodeInJavaScript is the same, but handles the case where Go expressions\n// are embedded within JavaScript.\n//\n// The only difference is that goCode normalises whitespace after the\n// closing brace pair, whereas goCodeInJavaScript retains all whitespace.\nvar goCode = getGoCodeParser(true)\nvar goCodeInJavaScript = getGoCodeParser(false)\n\nfunc getGoCodeParser(normalizeWhitespace bool) parse.Parser[Node] {\n\treturn parse.Func(func(pi *parse.Input) (n Node, ok bool, err error) {\n\t\t// Check the prefix first.\n\t\tif _, ok, err = dblOpenBraceWithOptionalPaddingOrNewLine.Parse(pi); err != nil || !ok {\n\t\t\treturn\n\t\t}\n\n\t\t// Once we have a prefix, we must have an expression that returns a string, with optional err.\n\t\tl := pi.Position().Line\n\t\tr := &GoCode{}\n\t\tif r.Expression, err = parseGo(\"go code\", pi, goexpression.Expression); err != nil {\n\t\t\treturn r, false, err\n\t\t}\n\n\t\tif l != pi.Position().Line {\n\t\t\tr.Multiline = true\n\t\t}\n\n\t\t// Clear any optional whitespace.\n\t\t_, _, _ = parse.OptionalWhitespace.Parse(pi)\n\n\t\t// }}\n\t\tif _, ok, err = dblCloseBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\t\terr = parse.Error(\"go code: missing close braces\", pi.Position())\n\t\t\treturn\n\t\t}\n\n\t\t// Parse trailing whitespace.\n\t\tws, _, err := parse.Whitespace.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn r, false, err\n\t\t}\n\t\tif normalizeWhitespace {\n\t\t\tif r.TrailingSpace, err = NewTrailingSpace(ws); err != nil {\n\t\t\t\treturn r, false, err\n\t\t\t}\n\t\t} else {\n\t\t\tr.TrailingSpace = TrailingSpace(ws)\n\t\t}\n\n\t\treturn r, true, nil\n\t})\n}\n"
  },
  {
    "path": "parser/v2/gocodeparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestGoCodeParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *GoCode\n\t}{\n\t\t{\n\t\t\tname:  \"basic expression\",\n\t\t\tinput: `{{ p := \"this\" }}`,\n\t\t\texpected: &GoCode{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p := \"this\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"basic expression, no space\",\n\t\t\tinput: `{{p:=\"this\"}}`,\n\t\t\texpected: &GoCode{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p:=\"this\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 2,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiline function decl\",\n\t\t\tinput: `{{\n\t\t\t\tp := func() {\n\t\t\t\t\tdosomething()\n\t\t\t\t}\n\t\t\t}}`,\n\t\t\texpected: &GoCode{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p := func() {\n\t\t\t\t\tdosomething()\n\t\t\t\t}`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 45,\n\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tMultiline: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"comments in expression\",\n\t\t\tinput: `{{\n\tone := \"one\"\n\ttwo := \"two\"\n\t// Comment in middle of expression.\n\tfour := \"four\"\n\t// Comment at end of expression.\n}}`,\n\t\t\texpected: &GoCode{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `one := \"one\"\n\ttwo := \"two\"\n\t// Comment in middle of expression.\n\tfour := \"four\"\n\t// Comment at end of expression.`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 117,\n\t\t\t\t\t\t\tLine:  5,\n\t\t\t\t\t\t\tCol:   33,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tTrailingSpace: SpaceNone,\n\t\t\t\tMultiline:     true,\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tan, ok, err := goCode.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tactual := an.(*GoCode)\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\n\t\t\t// Check the index.\n\t\t\tcut := tt.input[actual.Expression.Range.From.Index:actual.Expression.Range.To.Index]\n\t\t\tif tt.expected.Expression.Value != cut {\n\t\t\t\tt.Errorf(\"range, expected %q, got %q\", tt.expected.Expression.Value, cut)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/gocommentparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\nvar (\n\tgoSingleLineCommentStart = parse.String(\"//\")\n\tgoSingleLineCommentEnd   = parse.Any(parse.NewLine, parse.EOF[string]())\n)\n\ntype goSingleLineCommentParser struct{}\n\nvar goSingleLineComment = goSingleLineCommentParser{}\n\nfunc (p goSingleLineCommentParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\t// Comment start.\n\tstart := pi.Position()\n\tif _, ok, err = goSingleLineCommentStart.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\t// Once we've got the comment start sequence, parse anything until the end\n\t// sequence as the comment contents.\n\tc := &GoComment{}\n\tif c.Contents, ok, err = parse.StringUntil(goSingleLineCommentEnd).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"expected end comment literal '\\n' not found\", pi.Position())\n\t\treturn\n\t}\n\t// Return the comment.\n\tc.Multiline = false\n\tc.Range = NewRange(start, pi.Position())\n\treturn c, true, nil\n}\n\nvar (\n\tgoMultiLineCommentStart = parse.String(\"/*\")\n\tgoMultiLineCommentEnd   = parse.String(\"*/\")\n)\n\ntype goMultiLineCommentParser struct{}\n\nvar goMultiLineComment = goMultiLineCommentParser{}\n\nfunc (p goMultiLineCommentParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\t// Comment start.\n\tstart := pi.Position()\n\tif _, ok, err = goMultiLineCommentStart.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Once we've got the comment start sequence, parse anything until the end\n\t// sequence as the comment contents.\n\tc := &GoComment{}\n\tif c.Contents, ok, err = parse.StringUntil(goMultiLineCommentEnd).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"expected end comment literal '*/' not found\", start)\n\t\treturn\n\t}\n\t// Move past the end element.\n\t_, _, _ = goMultiLineCommentEnd.Parse(pi)\n\t// Return the comment.\n\tc.Multiline = true\n\tc.Range = NewRange(start, pi.Position())\n\treturn c, true, nil\n}\n\nvar goComment = parse.Any(goSingleLineComment, goMultiLineComment)\n"
  },
  {
    "path": "parser/v2/gocommentparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestGoCommentParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *GoComment\n\t}{\n\t\t{\n\t\t\tname: \"single line can have a newline at the end\",\n\t\t\tinput: `// single line comment\n`,\n\t\t\texpected: &GoComment{\n\t\t\t\tContents:  \" single line comment\",\n\t\t\t\tMultiline: false,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 22, Line: 0, Col: 22},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"single line comments can terminate the file\",\n\t\t\tinput: `// single line comment`,\n\t\t\texpected: &GoComment{\n\t\t\t\tContents:  \" single line comment\",\n\t\t\t\tMultiline: false,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 22, Line: 0, Col: 22},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"multiline comments can be on one line\",\n\t\t\tinput: `/* multiline comment, on one line */`,\n\t\t\texpected: &GoComment{\n\t\t\t\tContents:  \" multiline comment, on one line \",\n\t\t\t\tMultiline: true,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 36, Line: 0, Col: 36},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiline comments can span lines\",\n\t\t\tinput: `/* multiline comment,\non multiple lines */`,\n\t\t\texpected: &GoComment{\n\t\t\t\tContents:  \" multiline comment,\\non multiple lines \",\n\t\t\t\tMultiline: true,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 42, Line: 1, Col: 20},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := goComment.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCommentParserErrors(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected error\n\t}{\n\t\t{\n\t\t\tname:  \"unclosed multi-line Go comments result in an error\",\n\t\t\tinput: `/* unclosed Go comment`,\n\t\t\texpected: parse.Error(\"expected end comment literal '*/' not found\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 0,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   0,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tname:     \"single-line Go comment with no newline is allowed\",\n\t\t\tinput:    `// Comment with no newline`,\n\t\t\texpected: nil,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, _, err := goComment.Parse(input)\n\t\t\tif diff := cmp.Diff(tt.expected, err); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/goexpression/fuzz.sh",
    "content": "#!/bin/bash\necho If\ngo test -fuzz=FuzzIf -fuzztime=120s\necho For\ngo test -fuzz=FuzzFor -fuzztime=120s\necho Switch\ngo test -fuzz=FuzzSwitch -fuzztime=120s\necho Case\ngo test -fuzz=FuzzCaseStandard -fuzztime=120s\necho Default\ngo test -fuzz=FuzzCaseDefault -fuzztime=120s\necho TemplExpression\ngo test -fuzz=FuzzTemplExpression -fuzztime=120s\necho Expression\ngo test -fuzz=FuzzExpression -fuzztime=120s\necho SliceArgs\ngo test -fuzz=FuzzSliceArgs -fuzztime=120s\necho Funcs\ngo test -fuzz=FuzzFuncs -fuzztime=120s\n"
  },
  {
    "path": "parser/v2/goexpression/parse.go",
    "content": "package goexpression\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/scanner\"\n\t\"go/token\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nvar (\n\tErrContainerFuncNotFound = errors.New(\"parser error: templ container function not found\")\n\tErrExpectedNodeNotFound  = errors.New(\"parser error: expected node not found\")\n)\n\nvar defaultRegexp = regexp.MustCompile(`^default\\s*:`)\n\nfunc Case(content string) (start, end int, err error) {\n\tif !strings.HasPrefix(content, \"case \") && !defaultRegexp.MatchString(content) {\n\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t}\n\tprefix := \"switch {\\n\"\n\tsrc := prefix + content\n\tstart, end, err = extract(src, func(body []ast.Stmt) (start, end int, err error) {\n\t\tsw, ok := body[0].(*ast.SwitchStmt)\n\t\tif !ok {\n\t\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t\t}\n\t\tif sw.Body == nil || len(sw.Body.List) == 0 {\n\t\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t\t}\n\t\tstmt, ok := sw.Body.List[0].(*ast.CaseClause)\n\t\tif !ok {\n\t\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t\t}\n\t\tstart = int(stmt.Case) - 1\n\t\tend = int(stmt.Colon)\n\t\treturn start, end, nil\n\t})\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\t// Since we added a `switch {` prefix, we need to remove it.\n\tstart -= len(prefix)\n\tend -= len(prefix)\n\treturn start, end, nil\n}\n\nfunc If(content string) (start, end int, err error) {\n\tif !strings.HasPrefix(content, \"if\") {\n\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t}\n\treturn extract(content, func(body []ast.Stmt) (start, end int, err error) {\n\t\tstmt, ok := body[0].(*ast.IfStmt)\n\t\tif !ok {\n\t\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t\t}\n\t\tstart = int(stmt.If) + len(\"if\")\n\t\tend = latestEnd(start, stmt.Init, stmt.Cond)\n\t\treturn start, end, nil\n\t})\n}\n\nfunc For(content string) (start, end int, err error) {\n\tif !strings.HasPrefix(content, \"for\") {\n\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t}\n\treturn extract(content, func(body []ast.Stmt) (start, end int, err error) {\n\t\tstmt := body[0]\n\t\tswitch stmt := stmt.(type) {\n\t\tcase *ast.ForStmt:\n\t\t\tstart = int(stmt.For) + len(\"for\")\n\t\t\tend = latestEnd(start, stmt.Init, stmt.Cond, stmt.Post)\n\t\t\treturn start, end, nil\n\t\tcase *ast.RangeStmt:\n\t\t\tstart = int(stmt.For) + len(\"for\")\n\t\t\tend = latestEnd(start, stmt.Key, stmt.Value, stmt.X)\n\t\t\treturn start, end, nil\n\t\t}\n\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t})\n}\n\nfunc Switch(content string) (start, end int, err error) {\n\tif !strings.HasPrefix(content, \"switch\") {\n\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t}\n\treturn extract(content, func(body []ast.Stmt) (start, end int, err error) {\n\t\tstmt := body[0]\n\t\tswitch stmt := stmt.(type) {\n\t\tcase *ast.SwitchStmt:\n\t\t\tstart = int(stmt.Switch) + len(\"switch\")\n\t\t\tend = latestEnd(start, stmt.Init, stmt.Tag)\n\t\t\treturn start, end, nil\n\t\tcase *ast.TypeSwitchStmt:\n\t\t\tstart = int(stmt.Switch) + len(\"switch\")\n\t\t\tend = latestEnd(start, stmt.Init, stmt.Assign)\n\t\t\treturn start, end, nil\n\t\t}\n\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t})\n}\n\nfunc TemplExpression(src string) (start, end int, err error) {\n\tvar s scanner.Scanner\n\tfset := token.NewFileSet()\n\tfile := fset.AddFile(\"\", fset.Base(), len(src))\n\terrorHandler := func(pos token.Position, msg string) {\n\t\terr = fmt.Errorf(\"error parsing expression: %v\", msg)\n\t}\n\ts.Init(file, []byte(src), errorHandler, scanner.ScanComments)\n\n\t// Read chains of identifiers, e.g.:\n\t// components.Variable\n\t// components[0].Variable\n\t// components[\"name\"].Function()\n\t// functionCall(withLots(), func() { return true })\n\tep := NewExpressionParser()\n\tfor {\n\t\tpos, tok, lit := s.Scan()\n\t\tstop, err := ep.Insert(pos, tok, lit)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tif stop {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn 0, ep.End, nil\n}\n\nfunc Expression(src string) (start, end int, err error) {\n\tvar s scanner.Scanner\n\tfset := token.NewFileSet()\n\tfile := fset.AddFile(\"\", fset.Base(), len(src))\n\terrorHandler := func(pos token.Position, msg string) {\n\t\terr = fmt.Errorf(\"error parsing expression: %v\", msg)\n\t}\n\ts.Init(file, []byte(src), errorHandler, scanner.ScanComments)\n\n\t// Read chains of identifiers and constants up until RBRACE, e.g.:\n\t// true\n\t// 123.45 == true\n\t// components.Variable\n\t// components[0].Variable\n\t// components[\"name\"].Function()\n\t// functionCall(withLots(), func() { return true })\n\t// !true\n\tparenDepth := 0\n\tbracketDepth := 0\n\tbraceDepth := 0\nloop:\n\tfor {\n\t\tpos, tok, lit := s.Scan()\n\t\tif tok == token.EOF {\n\t\t\tbreak loop\n\t\t}\n\t\tswitch tok {\n\t\tcase token.LPAREN: // (\n\t\t\tparenDepth++\n\t\tcase token.RPAREN: // )\n\t\t\tend = int(pos)\n\t\t\tparenDepth--\n\t\tcase token.LBRACK: // [\n\t\t\tbracketDepth++\n\t\tcase token.RBRACK: // ]\n\t\t\tend = int(pos)\n\t\t\tbracketDepth--\n\t\tcase token.LBRACE: // {\n\t\t\tbraceDepth++\n\t\tcase token.RBRACE: // }\n\t\t\tbraceDepth--\n\t\t\tif braceDepth < 0 {\n\t\t\t\t// We've hit the end of the expression.\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tend = int(pos)\n\t\tcase token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING:\n\t\t\tend = int(pos) + len(lit) - 1\n\t\tcase token.SEMICOLON:\n\t\t\tcontinue\n\t\tcase token.COMMENT:\n\t\t\tend = int(pos) + len(lit) - 1\n\t\tcase token.ILLEGAL:\n\t\t\treturn 0, 0, fmt.Errorf(\"illegal token: %v\", lit)\n\t\tdefault:\n\t\t\tend = int(pos) + len(tok.String()) - 1\n\t\t}\n\t}\n\treturn start, end, nil\n}\n\nfunc SliceArgs(content string) (expr string, err error) {\n\tprefix := \"package main\\nvar templ_args = []any{\"\n\tsrc := prefix + content + \"}\"\n\n\tnode, parseErr := parser.ParseFile(token.NewFileSet(), \"\", src, parser.AllErrors)\n\tif node == nil {\n\t\treturn expr, parseErr\n\t}\n\n\tvar from, to int\n\tinspectFirstNode(node, func(n ast.Node) bool {\n\t\tdecl, ok := n.(*ast.CompositeLit)\n\t\tif !ok {\n\t\t\treturn true\n\t\t}\n\t\tfrom = int(decl.Lbrace)\n\t\tto = int(decl.Rbrace) - 1\n\t\tfor _, e := range decl.Elts {\n\t\t\tto = int(e.End()) - 1\n\t\t}\n\t\tif to > int(decl.Rbrace)-1 {\n\t\t\tto = int(decl.Rbrace) - 1\n\t\t}\n\t\tbetweenEndAndBrace := src[to : decl.Rbrace-1]\n\t\tvar hasCodeBetweenEndAndBrace bool\n\t\tfor _, r := range betweenEndAndBrace {\n\t\t\tif !unicode.IsSpace(r) {\n\t\t\t\thasCodeBetweenEndAndBrace = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif hasCodeBetweenEndAndBrace {\n\t\t\tto = int(decl.Rbrace) - 1\n\t\t}\n\t\treturn false\n\t})\n\n\treturn src[from:to], err\n}\n\n// Func returns the Go code up to the opening brace of the function body.\nfunc Func(content string) (name, expr string, err error) {\n\tprefix := \"package main\\n\"\n\tsrc := prefix + content\n\n\tnode, parseErr := parser.ParseFile(token.NewFileSet(), \"\", src, parser.AllErrors)\n\tif node == nil {\n\t\treturn name, expr, parseErr\n\t}\n\n\tinspectFirstNode(node, func(n ast.Node) bool {\n\t\t// Find the first function declaration.\n\t\tfn, ok := n.(*ast.FuncDecl)\n\t\tif !ok {\n\t\t\treturn true\n\t\t}\n\t\tstart := int(fn.Pos()) + len(\"func\")\n\t\tend := fn.Type.Params.End() - 1\n\t\tif len(src) < int(end) {\n\t\t\terr = errors.New(\"parser error: function identifier\")\n\t\t\treturn false\n\t\t}\n\t\texpr = strings.Clone(src[start:end])\n\t\tname = fn.Name.Name\n\t\treturn false\n\t})\n\n\treturn name, expr, err\n}\n\nfunc latestEnd(start int, nodes ...ast.Node) (end int) {\n\tend = start\n\tfor _, n := range nodes {\n\t\tif n == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif int(n.End())-1 > end {\n\t\t\tend = int(n.End()) - 1\n\t\t}\n\t}\n\treturn end\n}\n\nfunc inspectFirstNode(node ast.Node, f func(ast.Node) bool) {\n\tvar stop bool\n\tast.Inspect(node, func(n ast.Node) bool {\n\t\tif stop {\n\t\t\treturn true\n\t\t}\n\t\tif f(n) {\n\t\t\treturn true\n\t\t}\n\t\tstop = true\n\t\treturn false\n\t})\n}\n\n// Extract a Go expression from the content.\n// The Go expression starts at \"start\" and ends at \"end\".\n// The reader should skip until \"length\" to pass over the expression and into the next\n// logical block.\ntype Extractor func(body []ast.Stmt) (start, end int, err error)\n\nfunc extract(content string, extractor Extractor) (start, end int, err error) {\n\tprefix := \"package main\\nfunc templ_container() {\\n\"\n\tsrc := prefix + content\n\n\tnode, parseErr := parser.ParseFile(token.NewFileSet(), \"\", src, parser.AllErrors)\n\tif node == nil {\n\t\treturn 0, 0, parseErr\n\t}\n\n\tvar found bool\n\tinspectFirstNode(node, func(n ast.Node) bool {\n\t\t// Find the \"templ_container\" function.\n\t\tfn, ok := n.(*ast.FuncDecl)\n\t\tif !ok {\n\t\t\treturn true\n\t\t}\n\t\tif fn.Name == nil || fn.Name.Name != \"templ_container\" {\n\t\t\terr = ErrContainerFuncNotFound\n\t\t\treturn false\n\t\t}\n\t\tif fn.Body == nil || len(fn.Body.List) == 0 {\n\t\t\terr = ErrExpectedNodeNotFound\n\t\t\treturn false\n\t\t}\n\t\tfound = true\n\t\tstart, end, err = extractor(fn.Body.List)\n\t\treturn false\n\t})\n\tif !found {\n\t\treturn 0, 0, ErrExpectedNodeNotFound\n\t}\n\n\tstart -= len(prefix)\n\tend -= len(prefix)\n\n\tif end > len(content) {\n\t\tend = len(content)\n\t}\n\tif start > end {\n\t\tstart = end\n\t}\n\n\treturn start, end, err\n}\n"
  },
  {
    "path": "parser/v2/goexpression/parse_test.go",
    "content": "package goexpression\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nvar ifTests = []testInput{\n\t{\n\t\tname:  \"basic if\",\n\t\tinput: `true`,\n\t},\n\t{\n\t\tname:  \"if function call\",\n\t\tinput: `pkg.Func()`,\n\t},\n\t{\n\t\tname:  \"compound\",\n\t\tinput: \"x := val(); x > 3\",\n\t},\n\t{\n\t\tname:  \"if multiple\",\n\t\tinput: `x && y && (!z)`,\n\t},\n}\n\nfunc TestIf(t *testing.T) {\n\tprefix := \"if \"\n\tsuffixes := []string{\n\t\t\"{\\n<div>\\nif true content\\n\\t</div>}\",\n\t\t\" {\\n<div>\\nif true content\\n\\t</div>}\",\n\t}\n\tfor _, test := range ifTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, prefix, suffix, If))\n\t\t}\n\t}\n}\n\nfunc FuzzIf(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"{\\n<div>\\nif true content\\n\\t</div>}\",\n\t\t\" {\\n<div>\\nif true content\\n\\t</div>}\",\n\t}\n\tfor _, test := range ifTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(\"if \" + test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, src string) {\n\t\tstart, end, err := If(src)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t\tpanicIfInvalid(src, start, end)\n\t})\n}\n\nfunc panicIfInvalid(src string, start, end int) {\n\t_ = src[start:end]\n}\n\nvar forTests = []testInput{\n\t{\n\t\tname:  \"three component\",\n\t\tinput: `i := 0; i < 100; i++`,\n\t},\n\t{\n\t\tname:  \"three component, empty\",\n\t\tinput: `; ; i++`,\n\t},\n\t{\n\t\tname:  \"while\",\n\t\tinput: `n < 5`,\n\t},\n\t{\n\t\tname:  \"infinite\",\n\t\tinput: ``,\n\t},\n\t{\n\t\tname:  \"range with index\",\n\t\tinput: `k, v := range m`,\n\t},\n\t{\n\t\tname:  \"range with key only\",\n\t\tinput: `k := range m`,\n\t},\n\t{\n\t\tname:  \"channel receive\",\n\t\tinput: `x := range channel`,\n\t},\n}\n\nfunc TestFor(t *testing.T) {\n\tprefix := \"for \"\n\tsuffixes := []string{\n\t\t\" {\\n<div>\\nloop content\\n\\t</div>}\",\n\t}\n\tfor _, test := range forTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, prefix, suffix, For))\n\t\t}\n\t}\n}\n\nfunc FuzzFor(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\" {\",\n\t\t\" {}\",\n\t\t\" {\\n<div>\\nloop content\\n\\t</div>}\",\n\t}\n\tfor _, test := range forTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(\"for \" + test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, src string) {\n\t\tstart, end, err := For(src)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t\tpanicIfInvalid(src, start, end)\n\t})\n}\n\nvar switchTests = []testInput{\n\t{\n\t\tname:  \"switch\",\n\t\tinput: ``,\n\t},\n\t{\n\t\tname:  \"switch with expression\",\n\t\tinput: `x`,\n\t},\n\t{\n\t\tname:  \"switch with function call\",\n\t\tinput: `pkg.Func()`,\n\t},\n\t{\n\t\tname:  \"type switch\",\n\t\tinput: `x := x.(type)`,\n\t},\n}\n\nfunc TestSwitch(t *testing.T) {\n\tprefix := \"switch \"\n\tsuffixes := []string{\n\t\t\" {\\ncase 1:\\n\\t<div>\\n\\tcase 2:\\n\\t\\t<div>\\n\\tdefault:\\n\\t\\t<div>\\n\\t</div>}\",\n\t\t\" {\\ndefault:\\n\\t<div>\\n\\t</div>}\",\n\t\t\" {\\n}\",\n\t}\n\tfor _, test := range switchTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, prefix, suffix, Switch))\n\t\t}\n\t}\n}\n\nfunc FuzzSwitch(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\" {\",\n\t\t\" {}\",\n\t\t\" {\\n<div>\\nloop content\\n\\t</div>}\",\n\t}\n\tfor _, test := range switchTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, s string) {\n\t\tsrc := \"switch \" + s\n\t\tstart, end, err := For(src)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t\tpanicIfInvalid(src, start, end)\n\t})\n}\n\nvar caseTests = []testInput{\n\t{\n\t\tname:  \"case\",\n\t\tinput: `case 1:`,\n\t},\n\t{\n\t\tname:  \"case with expression\",\n\t\tinput: `case x > 3:`,\n\t},\n\t{\n\t\tname:  \"case with function call\",\n\t\tinput: `case pkg.Func():`,\n\t},\n\t{\n\t\tname:  \"case with multiple expressions\",\n\t\tinput: `case x > 3, x < 4:`,\n\t},\n\t{\n\t\tname:  \"case with multiple expressions and default\",\n\t\tinput: `case x > 3, x < 4, x == 5:`,\n\t},\n\t{\n\t\tname:  \"case with type switch\",\n\t\tinput: `case bool:`,\n\t},\n}\n\nfunc TestCase(t *testing.T) {\n\tsuffixes := []string{\n\t\t\"\\n<div>\\ncase 1 content\\n\\t</div>\\n\\tcase 3:\",\n\t\t\"\\ndefault:\\n\\t<div>\\n\\t</div>}\",\n\t\t\"\\n}\",\n\t}\n\tfor _, test := range caseTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, \"\", suffix, Case))\n\t\t}\n\t}\n}\n\nfunc FuzzCaseStandard(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\"\\n<div>\\ncase 1 content\\n\\t</div>\\n\\tcase 3:\",\n\t\t\"\\ndefault:\\n\\t<div>\\n\\t</div>}\",\n\t\t\"\\n}\",\n\t}\n\tfor _, test := range caseTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, src string) {\n\t\tstart, end, err := Case(src)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t\tpanicIfInvalid(src, start, end)\n\t})\n}\n\nfunc TestCaseDefault(t *testing.T) {\n\tsuffixes := []string{\n\t\t\"\\n<div>\\ncase 1 content\\n\\t</div>\\n\\tcase 3:\",\n\t\t\"\\ncase:\\n\\t<div>\\n\\t</div>}\",\n\t\t\"\\n}\",\n\t}\n\ttests := []testInput{\n\t\t{\n\t\t\tname:  \"default\",\n\t\t\tinput: `default:`,\n\t\t},\n\t\t{\n\t\t\tname:  \"default with padding\",\n\t\t\tinput: `default :`,\n\t\t},\n\t\t{\n\t\t\tname:  \"default with padding\",\n\t\t\tinput: `default   :`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, \"\", suffix, Case))\n\t\t}\n\t}\n}\n\nfunc FuzzCaseDefault(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\" \",\n\t\t\"\\n<div>\\ncase 1 content\\n\\t</div>\\n\\tcase 3:\",\n\t\t\"\\ncase:\\n\\t<div>\\n\\t</div>}\",\n\t\t\"\\n}\",\n\t}\n\tfor _, suffix := range suffixes {\n\t\tf.Add(\"default:\" + suffix)\n\t}\n\tf.Fuzz(func(t *testing.T, src string) {\n\t\tstart, end, err := Case(src)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t\tpanicIfInvalid(src, start, end)\n\t})\n}\n\nvar expressionTests = []testInput{\n\t{\n\t\tname:  \"string literal\",\n\t\tinput: `\"hello\"`,\n\t},\n\t{\n\t\tname:  \"string literal with escape\",\n\t\tinput: `\"hello\\n\"`,\n\t},\n\t{\n\t\tname:  \"backtick string literal\",\n\t\tinput: \"`hello`\",\n\t},\n\t{\n\t\tname:  \"backtick string literal containing double quote\",\n\t\tinput: \"`hello\" + `\"` + `world` + \"`\",\n\t},\n\t{\n\t\tname:  \"function call in package\",\n\t\tinput: `components.Other()`,\n\t},\n\t{\n\t\tname:  \"slice index call\",\n\t\tinput: `components[0].Other()`,\n\t},\n\t{\n\t\tname:  \"map index function call\",\n\t\tinput: `components[\"name\"].Other()`,\n\t},\n\t{\n\t\tname:  \"function literal\",\n\t\tinput: `components[\"name\"].Other(func() bool { return true })`,\n\t},\n\t{\n\t\tname: \"multiline function call\",\n\t\tinput: `component(map[string]string{\n\t\t\t\t\"namea\": \"name_a\",\n\t\t\t  \"nameb\": \"name_b\",\n\t\t\t})`,\n\t},\n\t{\n\t\tname:  \"call with braces and brackets\",\n\t\tinput: `templates.New(test{}, other())`,\n\t},\n\t{\n\t\tname:  \"bare variable\",\n\t\tinput: `component`,\n\t},\n\t{\n\t\tname:  \"boolean expression\",\n\t\tinput: `direction == \"newest\"`,\n\t},\n\t{\n\t\tname:  \"boolean expression with parens\",\n\t\tinput: `len(data.previousPageUrl) == 0`,\n\t},\n\t{\n\t\tname:  \"string concat\",\n\t\tinput: `direction + \"newest\"`,\n\t},\n\t{\n\t\tname: \"function call\",\n\t\tinput: `SplitRule(types.GroupMember{\n    UserID:   uuid.NewString(),\n    Username: \"user me\",\n}, []types.GroupMember{\n    {\n    UserID:   uuid.NewString(),\n    Username: \"user 1\",\n    },\n})`,\n\t},\n}\n\nfunc TestExpression(t *testing.T) {\n\tprefix := \"\"\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\"}\",\n\t\t\"\\t}\",\n\t\t\"  }\",\n\t}\n\tfor _, test := range expressionTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, prefix, suffix, Expression))\n\t\t}\n\t}\n}\n\nvar templExpressionTests = []testInput{\n\t{\n\t\tname:  \"function call in package\",\n\t\tinput: `components.Other()`,\n\t},\n\t{\n\t\tname:  \"slice index call\",\n\t\tinput: `components[0].Other()`,\n\t},\n\t{\n\t\tname:  \"map index function call\",\n\t\tinput: `components[\"name\"].Other()`,\n\t},\n\t{\n\t\tname: \"multiline chain call\",\n\t\tinput: `components.\n\tOther()`,\n\t},\n\t{\n\t\tname:  \"map index function call backtick literal\",\n\t\tinput: \"components[`name\" + `\"` + \"`].Other()\",\n\t},\n\t{\n\t\tname:  \"function literal\",\n\t\tinput: `components[\"name\"].Other(func() bool { return true })`,\n\t},\n\t{\n\t\tname: \"multiline function call\",\n\t\tinput: `component(map[string]string{\n\t\t\t\t\"namea\": \"name_a\",\n\t\t\t  \"nameb\": \"name_b\",\n\t\t\t})`,\n\t},\n\t{\n\t\tname: \"function call with slice of complex types\",\n\t\tinput: `tabs([]TabData{\n  {Name: \"A\"},\n  {Name: \"B\"},\n})`,\n\t},\n\t{\n\t\tname: \"function call with slice of explicitly named complex types\",\n\t\tinput: `tabs([]TabData{\n  TabData{Name: \"A\"},\n  TabData{Name: \"B\"},\n})`,\n\t},\n\t{\n\t\tname:  \"function call with empty slice of strings\",\n\t\tinput: `Inner([]string{})`,\n\t},\n\t{\n\t\tname:  \"function call with empty slice of maps\",\n\t\tinput: `Inner([]map[string]any{})`,\n\t},\n\t{\n\t\tname:  \"function call with empty slice of anon structs\",\n\t\tinput: `Inner([]map[string]struct{}{})`,\n\t},\n\t{\n\t\tname: \"function call with slice of pointers to complex types\",\n\t\tinput: `tabs([]*TabData{\n  &{Name: \"A\"},\n  &{Name: \"B\"},\n})`,\n\t},\n\t{\n\t\tname: \"function call with slice of pointers to explicitly named complex types\",\n\t\tinput: `tabs([]*TabData{\n  &TabData{Name: \"A\"},\n  &TabData{Name: \"B\"},\n})`,\n\t},\n\t{\n\t\tname: \"function call with array of explicit length\",\n\t\tinput: `tabs([2]TabData{\n  {Name: \"A\"},\n  {Name: \"B\"},\n})`,\n\t},\n\t{\n\t\tname: \"function call with array of inferred length\",\n\t\tinput: `tabs([...]TabData{\n  {Name: \"A\"},\n  {Name: \"B\"},\n})`,\n\t},\n\t{\n\t\tname: \"function call with function arg\",\n\t\tinput: `componentA(func(y []int) string {\n\t\treturn \"hi\"\n\t})`,\n\t},\n\t{\n\t\tname: \"function call with function called arg\",\n\t\tinput: `componentA(func(y []int) string {\n\t\treturn \"hi\"\n\t}())`,\n\t},\n\t{\n\t\tname:  \"call with braces and brackets\",\n\t\tinput: `templates.New(test{}, other())`,\n\t},\n\t{\n\t\tname:  \"generic call\",\n\t\tinput: `templates.New(toString[[]int](data))`,\n\t},\n\t{\n\t\tname:  \"struct method call\",\n\t\tinput: `typeName{}.Method()`,\n\t},\n\t{\n\t\tname:  \"struct method call in other package\",\n\t\tinput: \"layout.DefaultLayout{}.Compile()\",\n\t},\n\t{\n\t\tname:  \"bare variable\",\n\t\tinput: `component`,\n\t},\n}\n\nfunc TestTemplExpression(t *testing.T) {\n\tprefix := \"\"\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\"}\",\n\t\t\"\\t}\",\n\t\t\"  }\",\n\t\t\"</div>\",\n\t\t\"<p>/</p>\",\n\t\t\" just some text\",\n\t\t\" { <div>Child content</div> }\",\n\t}\n\tfor _, test := range templExpressionTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, prefix, suffix, TemplExpression))\n\t\t}\n\t}\n}\n\nfunc FuzzTemplExpression(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\" }\",\n\t\t\" }}</a>\\n}\",\n\t\t\"...\",\n\t}\n\tfor _, test := range expressionTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, s string) {\n\t\tsrc := \"switch \" + s\n\t\tstart, end, err := TemplExpression(src)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t\tpanicIfInvalid(src, start, end)\n\t})\n}\n\nfunc FuzzExpression(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\" }\",\n\t\t\" }}</a>\\n}\",\n\t\t\"...\",\n\t}\n\tfor _, test := range expressionTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, s string) {\n\t\tsrc := \"switch \" + s\n\t\tstart, end, err := Expression(src)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t\tpanicIfInvalid(src, start, end)\n\t})\n}\n\nvar sliceArgsTests = []testInput{\n\t{\n\t\tname:  \"no input\",\n\t\tinput: ``,\n\t},\n\t{\n\t\tname:  \"single input\",\n\t\tinput: `nil`,\n\t},\n\t{\n\t\tname:  \"inputs to function call\",\n\t\tinput: `a, b, \"c\"`,\n\t},\n\t{\n\t\tname:  \"function call in package\",\n\t\tinput: `components.Other()`,\n\t},\n\t{\n\t\tname:  \"slice index call\",\n\t\tinput: `components[0].Other()`,\n\t},\n\t{\n\t\tname:  \"map index function call\",\n\t\tinput: `components[\"name\"].Other()`,\n\t},\n\t{\n\t\tname:  \"function literal\",\n\t\tinput: `components[\"name\"].Other(func() bool { return true })`,\n\t},\n\t{\n\t\tname: \"multiline function call\",\n\t\tinput: `component(map[string]string{\n\t\t\t\t\"namea\": \"name_a\",\n\t\t\t  \"nameb\": \"name_b\",\n\t\t\t})`,\n\t},\n\t{\n\t\tname:  \"package name, but no variable or function\",\n\t\tinput: `fmt.`,\n\t},\n}\n\nfunc TestSliceArgs(t *testing.T) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\"}\",\n\t\t\"}</a>\\n}\\nvar x = []struct {}{}\",\n\t}\n\tfor _, test := range sliceArgsTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), func(t *testing.T) {\n\t\t\t\texpr, err := SliceArgs(test.input + suffix)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"failed to parse slice args: %v\", err)\n\t\t\t\t}\n\t\t\t\tif diff := cmp.Diff(test.input, expr); diff != \"\" {\n\t\t\t\t\tt.Error(diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc FuzzSliceArgs(f *testing.F) {\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\"}\",\n\t\t\" }\",\n\t\t\"}</a>\\n}\\nvar x = []struct {}{}\",\n\t}\n\tfor _, test := range sliceArgsTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, s string) {\n\t\t_, err := SliceArgs(s)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t})\n}\n\nfunc TestChildren(t *testing.T) {\n\tprefix := \"\"\n\tsuffixes := []string{\n\t\t\" }\",\n\t\t\" } <div>Other content</div>\",\n\t\t\"\", // End of file.\n\t}\n\ttests := []testInput{\n\t\t{\n\t\t\tname:  \"children\",\n\t\t\tinput: `children...`,\n\t\t},\n\t\t{\n\t\t\tname:  \"function\",\n\t\t\tinput: `components.Spread()...`,\n\t\t},\n\t\t{\n\t\t\tname:  \"alternative variable\",\n\t\t\tinput: `components...`,\n\t\t},\n\t\t{\n\t\t\tname:  \"index\",\n\t\t\tinput: `groups[0]...`,\n\t\t},\n\t\t{\n\t\t\tname:  \"map\",\n\t\t\tinput: `components[\"name\"]...`,\n\t\t},\n\t\t{\n\t\t\tname:  \"map func key\",\n\t\t\tinput: `components[getKey(ctx)]...`,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), run(test, prefix, suffix, Expression))\n\t\t}\n\t}\n}\n\nvar funcTests = []testInput{\n\t{\n\t\tname:  \"void func\",\n\t\tinput: `myfunc()`,\n\t},\n\t{\n\t\tname:  \"receiver func\",\n\t\tinput: `(r recv) myfunc()`,\n\t},\n}\n\nfunc FuzzFuncs(f *testing.F) {\n\tprefix := \"func \"\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\"}\",\n\t\t\" }\",\n\t\t\"}</a>\\n}\\nvar x = []struct {}{}\",\n\t}\n\tfor _, test := range funcTests {\n\t\tfor _, suffix := range suffixes {\n\t\t\tf.Add(prefix + test.input + suffix)\n\t\t}\n\t}\n\tf.Fuzz(func(t *testing.T, s string) {\n\t\t_, _, err := Func(s)\n\t\tif err != nil {\n\t\t\tt.Skip()\n\t\t\treturn\n\t\t}\n\t})\n}\n\nfunc TestFunc(t *testing.T) {\n\tprefix := \"func \"\n\tsuffixes := []string{\n\t\t\"\",\n\t\t\"}\",\n\t\t\"}\\nvar x = []struct {}{}\",\n\t\t\"}\\nfunc secondFunc() {}\",\n\t}\n\tfor _, test := range funcTests {\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", test.name, i), func(t *testing.T) {\n\t\t\t\tname, expr, err := Func(prefix + test.input + suffix)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Errorf(\"failed to parse slice args: %v\", err)\n\t\t\t\t}\n\t\t\t\tif diff := cmp.Diff(test.input, expr); diff != \"\" {\n\t\t\t\t\tt.Error(diff)\n\t\t\t\t}\n\t\t\t\tif diff := cmp.Diff(\"myfunc\", name); diff != \"\" {\n\t\t\t\t\tt.Error(diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n}\n\ntype testInput struct {\n\tname        string\n\tinput       string\n\texpectedErr error\n}\n\ntype extractor func(content string) (start, end int, err error)\n\nfunc run(test testInput, prefix, suffix string, e extractor) func(t *testing.T) {\n\treturn func(t *testing.T) {\n\t\tsrc := prefix + test.input + suffix\n\t\tstart, end, err := e(src)\n\t\tif test.expectedErr == nil && err != nil {\n\t\t\tt.Fatalf(\"expected nil error got error type %T: %v\", err, err)\n\t\t}\n\t\tif test.expectedErr != nil && err == nil {\n\t\t\tt.Fatalf(\"expected err %q, got %v\", test.expectedErr.Error(), err)\n\t\t}\n\t\tif test.expectedErr != nil && err != nil && test.expectedErr.Error() != err.Error() {\n\t\t\tt.Fatalf(\"expected err %q, got %q\", test.expectedErr.Error(), err.Error())\n\t\t}\n\t\tactual := src[start:end]\n\t\tif diff := cmp.Diff(test.input, actual); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "parser/v2/goexpression/parsebench_test.go",
    "content": "package goexpression\n\nimport \"testing\"\n\nvar testStringExpression = `\"this string expression\" } \n<div>\n  But afterwards, it keeps searching.\n<div>\n\n<div>\n  But that's not right, we can stop searching. It won't find anything valid.\n</div>\n\n<div>\n  Certainly not later in the file.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n`\n\nfunc BenchmarkExpression(b *testing.B) {\n\t// Baseline...\n\t// BenchmarkExpression-10              6484            184862 ns/op\n\t// Updated...\n\t// BenchmarkExpression-10           3942538               279.6 ns/op\n\tfor n := 0; n < b.N; n++ {\n\t\tstart, end, err := Expression(testStringExpression)\n\t\tif err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t\tif start != 0 || end != 24 {\n\t\t\tb.Fatalf(\"expected 0, 24, got %d, %d\", start, end)\n\t\t}\n\t}\n}\n\nvar testTemplExpression = `templates.CallMethod(map[string]any{\n\t\"name\": \"this string expression\",\n})\n\n<div>\n  But afterwards, it keeps searching.\n<div>\n\n<div>\n  But that's not right, we can stop searching. It won't find anything valid.\n</div>\n\n<div>\n  Certainly not later in the file.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n\n<div>\n\tIt's going to try all the tokens.\n  )}]@<+.\n</div>\n`\n\nfunc BenchmarkTemplExpression(b *testing.B) {\n\t// BenchmarkTemplExpression-10         2694            431934 ns/op\n\t// Updated...\n\t// BenchmarkTemplExpression-10      1339399               897.6 ns/op\n\tfor n := 0; n < b.N; n++ {\n\t\tstart, end, err := TemplExpression(testTemplExpression)\n\t\tif err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t\tif start != 0 || end != 74 {\n\t\t\tb.Fatalf(\"expected 0, 74, got %d, %d\", start, end)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "parser/v2/goexpression/scanner.go",
    "content": "package goexpression\n\nimport (\n\t\"fmt\"\n\t\"go/token\"\n)\n\ntype Stack[T any] []T\n\nfunc (s *Stack[T]) Push(v T) {\n\t*s = append(*s, v)\n}\n\nfunc (s *Stack[T]) Pop() (v T) {\n\tif len(*s) == 0 {\n\t\treturn v\n\t}\n\tv = (*s)[len(*s)-1]\n\t*s = (*s)[:len(*s)-1]\n\treturn v\n}\n\nfunc (s *Stack[T]) Peek() (v T) {\n\tif len(*s) == 0 {\n\t\treturn v\n\t}\n\treturn (*s)[len(*s)-1]\n}\n\nvar goTokenOpenToClose = map[token.Token]token.Token{\n\ttoken.LPAREN: token.RPAREN,\n\ttoken.LBRACE: token.RBRACE,\n\ttoken.LBRACK: token.RBRACK,\n}\n\nvar goTokenCloseToOpen = map[token.Token]token.Token{\n\ttoken.RPAREN: token.LPAREN,\n\ttoken.RBRACE: token.LBRACE,\n\ttoken.RBRACK: token.LBRACK,\n}\n\ntype ErrUnbalanced struct {\n\tToken token.Token\n}\n\nfunc (e ErrUnbalanced) Error() string {\n\treturn fmt.Sprintf(\"unbalanced '%s'\", e.Token)\n}\n\nfunc NewExpressionParser() *ExpressionParser {\n\treturn &ExpressionParser{\n\t\tStack:    make(Stack[token.Token], 0),\n\t\tPrevious: token.PERIOD,\n\t\tFns:      make(Stack[int], 0),\n\t}\n}\n\ntype ExpressionParser struct {\n\tStack    Stack[token.Token]\n\tEnd      int\n\tPrevious token.Token\n\tFns      Stack[int] // Stack of function depths.\n}\n\nfunc (ep *ExpressionParser) setEnd(pos token.Pos, tok token.Token, lit string) {\n\tep.End = int(pos) + len(tokenString(tok, lit)) - 1\n}\n\nfunc (ep *ExpressionParser) hasSpaceBeforeCurrentToken(pos token.Pos) bool {\n\treturn (int(pos) - 1) > ep.End\n}\n\nfunc (ep *ExpressionParser) isTopLevel() bool {\n\treturn len(ep.Fns) == 0 && len(ep.Stack) == 0\n}\n\nfunc (ep *ExpressionParser) Insert(\n\tpos token.Pos,\n\ttok token.Token,\n\tlit string,\n) (stop bool, err error) {\n\tdefer func() {\n\t\tep.Previous = tok\n\t}()\n\n\t// If we've reach the end of the file, terminate reading.\n\tif tok == token.EOF {\n\t\t// If the EOF was reached, but we're not at the top level, we must have an unbalanced expression.\n\t\tif !ep.isTopLevel() {\n\t\t\treturn true, ErrUnbalanced{ep.Stack.Pop()}\n\t\t}\n\t\treturn true, nil\n\t}\n\n\t// Handle function literals e.g. func() { fmt.Println(\"Hello\") }\n\t// By pushing the current depth onto the stack, we prevent stopping\n\t// until we've closed the function.\n\tif tok == token.FUNC {\n\t\tep.Fns.Push(len(ep.Stack))\n\t\tep.setEnd(pos, tok, lit)\n\t\treturn false, nil\n\t}\n\t// If we're opening a pair, we don't stop until we've closed it.\n\tif _, isOpener := goTokenOpenToClose[tok]; isOpener {\n\t\t// If we're at an open brace, at the top level, where a space has been used, stop.\n\t\tif tok == token.LBRACE && ep.isTopLevel() {\n\t\t\t// Previous was paren, e.g. () {\n\t\t\tif ep.Previous == token.RPAREN {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\t// Previous was ident that isn't a type.\n\t\t\t// In `name {`, `name` is considered to be a variable.\n\t\t\t// In `name{`, `name` is considered to be a type name.\n\t\t\tif ep.Previous == token.IDENT && ep.hasSpaceBeforeCurrentToken(pos) {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t\tep.Stack.Push(tok)\n\t\tep.setEnd(pos, tok, lit)\n\t\treturn false, nil\n\t}\n\tif opener, isCloser := goTokenCloseToOpen[tok]; isCloser {\n\t\tif len(ep.Stack) == 0 {\n\t\t\t// We've got a close token, but there's nothing to close, so we must be done.\n\t\t\treturn true, nil\n\t\t}\n\t\tactual := ep.Stack.Pop()\n\t\tif !isCloser {\n\t\t\treturn false, ErrUnbalanced{tok}\n\t\t}\n\t\tif actual != opener {\n\t\t\treturn false, ErrUnbalanced{tok}\n\t\t}\n\t\tif tok == token.RBRACE {\n\t\t\t// If we're closing a function, pop the function depth.\n\t\t\tif len(ep.Stack) == ep.Fns.Peek() {\n\t\t\t\tep.Fns.Pop()\n\t\t\t}\n\t\t}\n\t\tep.setEnd(pos, tok, lit)\n\t\treturn false, nil\n\t}\n\t// If we're in a function literal slice, or pair, we allow anything until we close it.\n\tif len(ep.Fns) > 0 || len(ep.Stack) > 0 {\n\t\tep.setEnd(pos, tok, lit)\n\t\treturn false, nil\n\t}\n\t// We allow an ident to follow a period or a closer.\n\t// e.g. \"package.name\", \"typeName{field: value}.name()\".\n\t// or \"call().name\", \"call().name()\".\n\t// But not \"package .name\" or \"typeName{field: value} .name()\".\n\tif tok == token.IDENT && (ep.Previous == token.PERIOD || isCloser(ep.Previous)) {\n\t\tif isCloser(ep.Previous) && ep.hasSpaceBeforeCurrentToken(pos) {\n\t\t\t// This token starts later than the last ending, which means\n\t\t\t// there's a space.\n\t\t\treturn true, nil\n\t\t}\n\t\tep.setEnd(pos, tok, lit)\n\t\treturn false, nil\n\t}\n\tif tok == token.PERIOD && (ep.Previous == token.IDENT || isCloser(ep.Previous)) {\n\t\tep.setEnd(pos, tok, lit)\n\t\treturn false, nil\n\t}\n\n\t// No match, so stop.\n\treturn true, nil\n}\n\nfunc tokenString(tok token.Token, lit string) string {\n\tif tok.IsKeyword() || tok.IsOperator() {\n\t\treturn tok.String()\n\t}\n\treturn lit\n}\n\nfunc isCloser(tok token.Token) bool {\n\t_, ok := goTokenCloseToOpen[tok]\n\treturn ok\n}\n"
  },
  {
    "path": "parser/v2/goexpression/testdata/fuzz/FuzzCaseDefault/3c6f43d3ec8a900b",
    "content": "go test fuzz v1\nstring(\"default0\")\n"
  },
  {
    "path": "parser/v2/goexpression/testdata/fuzz/FuzzCaseDefault/986e7bc325c7890c",
    "content": "go test fuzz v1\nstring(\"default:{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{`0\\r000000\")\n"
  },
  {
    "path": "parser/v2/goexpression/testdata/fuzz/FuzzCaseDefault/d8a9a4cd9fc8cb11",
    "content": "go test fuzz v1\nstring(\"default\")\n"
  },
  {
    "path": "parser/v2/goexpression/testdata/fuzz/FuzzExpression/ac5d99902f5e7914",
    "content": "go test fuzz v1\nstring(\"#\")\n"
  },
  {
    "path": "parser/v2/goexpression/testdata/fuzz/FuzzFuncs/46c9ed6c9d427bd2",
    "content": "go test fuzz v1\nstring(\"func\")\n"
  },
  {
    "path": "parser/v2/goexpression/testdata/fuzz/FuzzIf/7a174efc13e3fdd6",
    "content": "go test fuzz v1\nstring(\"(\")\n"
  },
  {
    "path": "parser/v2/goparser.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\nfunc parseGoFuncDecl(prefix string, pi *parse.Input) (name string, expression Expression, err error) {\n\tprefix = prefix + \" \"\n\tfrom := pi.Index()\n\tsrc, _ := pi.Peek(-1)\n\tsrc = strings.TrimPrefix(src, prefix)\n\tname, expr, err := goexpression.Func(\"func \" + src)\n\tif err != nil {\n\t\treturn name, expression, parse.Error(fmt.Sprintf(\"invalid %s declaration: %v\", prefix, err.Error()), pi.Position())\n\t}\n\tpi.Take(len(prefix) + len(expr))\n\tto := pi.Position()\n\treturn name, NewExpression(expr, pi.PositionAt(from+len(prefix)), to), nil\n}\n\nfunc parseTemplFuncDecl(pi *parse.Input) (name string, expression Expression, err error) {\n\treturn parseGoFuncDecl(\"templ\", pi)\n}\n\nfunc parseCSSFuncDecl(pi *parse.Input) (name string, expression Expression, err error) {\n\treturn parseGoFuncDecl(\"css\", pi)\n}\n\nfunc parseGoSliceArgs(pi *parse.Input) (r Expression, err error) {\n\tfrom := pi.Position()\n\tsrc, _ := pi.Peek(-1)\n\texpr, err := goexpression.SliceArgs(src)\n\tif err != nil {\n\t\treturn r, err\n\t}\n\tpi.Take(len(expr))\n\tto := pi.Position()\n\treturn NewExpression(expr, from, to), nil\n}\n\nfunc peekPrefix(pi *parse.Input, prefixes ...string) bool {\n\tfor _, prefix := range prefixes {\n\t\tpp, ok := pi.Peek(len(prefix))\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tif prefix == pp {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype extractor func(content string) (start, end int, err error)\n\nfunc parseGo(name string, pi *parse.Input, e extractor) (r Expression, err error) {\n\tfrom := pi.Index()\n\tsrc, _ := pi.Peek(-1)\n\tstart, end, err := e(src)\n\tif err != nil {\n\t\treturn r, parse.Error(fmt.Sprintf(\"%s: invalid go expression: %v\", name, err.Error()), pi.Position())\n\t}\n\texpr := src[start:end]\n\tpi.Take(end)\n\treturn NewExpression(expr, pi.PositionAt(from+start), pi.PositionAt(from+end)), nil\n}\n"
  },
  {
    "path": "parser/v2/htmlcommentparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\nvar htmlCommentStart = parse.String(\"<!--\")\nvar htmlCommentEnd = parse.String(\"--\")\n\ntype htmlCommentParser struct {\n}\n\nvar htmlComment = htmlCommentParser{}\n\nfunc (p htmlCommentParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\t// Comment start.\n\tstart := pi.Position()\n\tif _, ok, err = htmlCommentStart.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Once we've got the comment start sequence, parse anything until the end\n\t// sequence as the comment contents.\n\tc := &HTMLComment{}\n\tif c.Contents, ok, err = parse.StringUntil(htmlCommentEnd).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"expected end comment literal '-->' not found\", start)\n\t\treturn\n\t}\n\t// Cut the end element.\n\t_, _, _ = htmlCommentEnd.Parse(pi)\n\n\t// Cut the gt.\n\tif _, ok, err = gt.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"comment contains invalid sequence '--'\", pi.Position())\n\t\treturn\n\t}\n\n\tc.Range = NewRange(start, pi.Position())\n\treturn c, true, nil\n}\n"
  },
  {
    "path": "parser/v2/htmlcommentparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestHTMLCommentParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *HTMLComment\n\t}{\n\t\t{\n\t\t\tname:  \"comment - single line\",\n\t\t\tinput: `<!-- single line comment -->`,\n\t\t\texpected: &HTMLComment{\n\t\t\t\tContents: \" single line comment \",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\tIndex: 0,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t},\n\t\t\t\t\tTo: Position{\n\t\t\t\t\t\tIndex: 28,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   28,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"comment - no whitespace\",\n\t\t\tinput: `<!--no whitespace between sequence open and close-->`,\n\t\t\texpected: &HTMLComment{\n\t\t\t\tContents: \"no whitespace between sequence open and close\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\tIndex: 0,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t},\n\t\t\t\t\tTo: Position{\n\t\t\t\t\t\tIndex: 52,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   52,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"comment - multiline\",\n\t\t\tinput: `<!-- multiline\n\t\t\t\t\t\t\t\tcomment\n\t\t\t\t\t-->`,\n\t\t\texpected: &HTMLComment{\n\t\t\t\tContents: ` multiline\n\t\t\t\t\t\t\t\tcomment\n\t\t\t\t\t`,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\tIndex: 0,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t},\n\t\t\t\t\tTo: Position{\n\t\t\t\t\t\tIndex: 39,\n\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"comment - with tag\",\n\t\t\tinput: `<!-- <p class=\"test\">tag</p> -->`,\n\t\t\texpected: &HTMLComment{\n\t\t\t\tContents: ` <p class=\"test\">tag</p> `,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\tIndex: 0,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t},\n\t\t\t\t\tTo: Position{\n\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   32,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"comments can contain tags\",\n\t\t\tinput: `<!-- <div> hello world </div> -->`,\n\t\t\texpected: &HTMLComment{\n\t\t\t\tContents: ` <div> hello world </div> `,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\tIndex: 0,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t},\n\t\t\t\t\tTo: Position{\n\t\t\t\t\t\tIndex: 33,\n\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\tCol:   33,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := htmlComment.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestHTMLCommentParserErrors(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected error\n\t}{\n\t\t{\n\t\t\tname:  \"unclosed HTML comment\",\n\t\t\tinput: `<!-- unclosed HTML comment`,\n\t\t\texpected: parse.Error(\"expected end comment literal '-->' not found\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 0,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   0,\n\t\t\t\t}),\n\t\t},\n\t\t{\n\t\t\tname:  \"comment in comment\",\n\t\t\tinput: `<!-- <-- other --> -->`,\n\t\t\texpected: parse.Error(\"comment contains invalid sequence '--'\", parse.Position{\n\t\t\t\tIndex: 8,\n\t\t\t\tLine:  0,\n\t\t\t\tCol:   8,\n\t\t\t}),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, _, err := htmlComment.Parse(input)\n\t\t\tif diff := cmp.Diff(tt.expected, err); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/ifexpressionparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\nvar ifExpression ifExpressionParser\n\nvar untilElseIfElseOrEnd = parse.Any(StripType(elseIfExpression), StripType(elseExpression), StripType(closeBraceWithOptionalPadding))\n\ntype ifExpressionParser struct{}\n\n// Parsers return:\n//  as much of a Node as they can\n//  matched=true if the start of a complete, incomplete or invalid node was found, e.g. \"if \" or \"{ \"\n//  err if an error occurred or a node was started and not completed\n\nfunc (ifExpressionParser) Parse(pi *parse.Input) (n Node, matched bool, err error) {\n\tstart := pi.Index()\n\n\tif !peekPrefix(pi, \"if \") {\n\t\treturn nil, false, nil\n\t}\n\n\t// Parse the Go if expression using the Go parser.\n\tr := &IfExpression{}\n\tif r.Expression, err = parseGo(\"if\", pi, goexpression.If); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Eat \" {\\n\".\n\tif _, matched, err = parse.All(openBraceWithOptionalPadding, parse.NewLine).Parse(pi); err != nil || !matched {\n\t\terr = parse.Error(\"if: \"+unterminatedMissingCurly, pi.PositionAt(start))\n\t\treturn r, true, err\n\t}\n\n\t// Once we've had the start of an if block, we must conclude the block.\n\n\t// Read the 'Then' nodes.\n\t// If there's no match, there's a problem in the template nodes.\n\tnp := newTemplateNodeParser(untilElseIfElseOrEnd, \"else expression or closing brace\")\n\tvar thenNodes Nodes\n\tif thenNodes, matched, err = np.Parse(pi); err != nil || !matched {\n\t\t// Populate the nodes anyway, so that the LSP can use them.\n\t\tr.Then = thenNodes.Nodes\n\t\treturn r, true, parse.Error(\"if: expected nodes, but none were found\", pi.Position())\n\t}\n\tr.Then = thenNodes.Nodes\n\n\t// Read the optional 'ElseIf' Nodes.\n\tif r.ElseIfs, _, err = parse.ZeroOrMore(elseIfExpression).Parse(pi); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Read the optional 'Else' Nodes.\n\tvar elseNodes Nodes\n\tif elseNodes, _, err = elseExpression.Parse(pi); err != nil {\n\t\t// Populate the nodes anyway, so that the LSP can use them.\n\t\tr.Else = elseNodes.Nodes\n\t\treturn r, true, err\n\t}\n\tr.Else = elseNodes.Nodes\n\n\t// Read the required closing brace.\n\tif _, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !matched {\n\t\treturn r, true, parse.Error(\"if: expected closing brace\", pi.Position())\n\t}\n\n\tr.Range = NewRange(pi.PositionAt(start), pi.Position())\n\treturn r, true, nil\n}\n\nvar elseIfExpression parse.Parser[ElseIfExpression] = elseIfExpressionParser{}\n\ntype elseIfExpressionParser struct{}\n\nfunc (elseIfExpressionParser) Parse(pi *parse.Input) (r ElseIfExpression, matched bool, err error) {\n\tstart := pi.Index()\n\n\t// Check the prefix first.\n\tif _, matched, err = parse.All(parse.OptionalWhitespace, closeBrace, parse.OptionalWhitespace, parse.String(\"else if\")).Parse(pi); err != nil || !matched {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Rewind to the start of the `if` statement.\n\tpi.Seek(pi.Index() - 2)\n\t// Parse the Go if expression.\n\tif r.Expression, err = parseGo(\"else if\", pi, goexpression.If); err != nil {\n\t\treturn r, false, err\n\t}\n\n\t// Eat \" {\\n\".\n\tif _, matched, err = parse.All(openBraceWithOptionalPadding, parse.NewLine).Parse(pi); err != nil || !matched {\n\t\terr = parse.Error(\"else if: \"+unterminatedMissingCurly, pi.PositionAt(start))\n\t\treturn\n\t}\n\n\t// Once we've had the start of an if block, we must conclude the block.\n\n\t// Read the 'Then' nodes.\n\t// If there's no match, there's a problem in the template nodes.\n\tnp := newTemplateNodeParser(untilElseIfElseOrEnd, \"else expression or closing brace\")\n\tvar thenNodes Nodes\n\tif thenNodes, matched, err = np.Parse(pi); err != nil || !matched {\n\t\terr = parse.Error(\"if: expected nodes, but none were found\", pi.Position())\n\t\treturn\n\t}\n\tr.Then = thenNodes.Nodes\n\n\tr.Range = NewRange(pi.PositionAt(start), pi.Position())\n\treturn r, true, nil\n}\n\nvar endElseParser = parse.All(\n\tparse.Rune('}'),\n\tparse.OptionalWhitespace,\n\tparse.String(\"else\"),\n\tparse.OptionalWhitespace,\n\tparse.Rune('{'),\n\tparse.OptionalWhitespace)\n\nvar elseExpression parse.Parser[Nodes] = elseExpressionParser{}\n\ntype elseExpressionParser struct{}\n\nfunc (elseExpressionParser) Parse(in *parse.Input) (r Nodes, matched bool, err error) {\n\tstart := in.Index()\n\n\t// } else {\n\tif _, matched, err = endElseParser.Parse(in); err != nil || !matched {\n\t\tin.Seek(start)\n\t\treturn\n\t}\n\n\t// Else contents\n\tif r, matched, err = newTemplateNodeParser(closeBraceWithOptionalPadding, \"else expression closing brace\").Parse(in); err != nil || !matched {\n\t\tin.Seek(start)\n\t\treturn\n\t}\n\n\treturn r, true, nil\n}\n"
  },
  {
    "path": "parser/v2/ifexpressionparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestIfExpression(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *IfExpression\n\t}{\n\t\t{\n\t\t\tname: \"if: simple expression\",\n\t\t\tinput: `if p.Test {\n<span>\n  { \"span content\" }\n</span>\n}\n`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.Test`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   9,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 17, Line: 1, Col: 5},\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 18,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 21,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\n  \"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 37,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   18,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 1, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 48, Line: 4, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 49, Line: 4, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: else\",\n\t\t\tinput: `if p.A {\n\t{ \"A\" }\n} else {\n\t{ \"B\" }\n}`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.A`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"A\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tElse: []Node{\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 33,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 37, Line: 4, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: expressions can have a space after the opening brace\",\n\t\t\tinput: `if p.Test {` + \" \" + `\n  text\n}\n`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.Test`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   9,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 13,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"  \"},\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tValue: \"text\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 15, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 19, Line: 1, Col: 6},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 21, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: simple expression, without spaces\",\n\t\t\tinput: `if p.Test {\n<span>\n  { \"span content\" }\n</span>\n}\n`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.Test`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   9,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 17, Line: 1, Col: 5},\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 18,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 21,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\n  \"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 37,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   18,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 1, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 48, Line: 4, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 49, Line: 4, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: else, without spaces\",\n\t\t\tinput: `if p.A{\n\t{ \"A\" }\n} else {\n\t{ \"B\" }\n}`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.A`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 8,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"A\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tElse: []Node{\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 29,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 36, Line: 4, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: nested\",\n\t\t\tinput: `if p.A {\n\t\t\t\t\tif p.B {\n\t\t\t\t\t\t<div>{ \"B\" }</div>\n\t\t\t\t\t}\n\t\t\t\t}`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.A`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\\t\\t\\t\"},\n\t\t\t\t\t&IfExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.B`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 17,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 20,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 29,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\\t\\t\\t\\t\\t\"},\n\t\t\t\t\t\t\t&Element{\n\t\t\t\t\t\t\t\tName: \"div\",\n\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 30, Line: 2, Col: 7},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 33, Line: 2, Col: 10},\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 36,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   13,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 39,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 29, Line: 2, Col: 6},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 53, Line: 3, Col: 5},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 14, Line: 1, Col: 5},\n\t\t\t\t\t\t\tTo:   Position{Index: 54, Line: 3, Col: 6},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 54,\n\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 59,\n\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\\t\\t\\t\\t\"},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 60, Line: 4, Col: 5},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: else if\",\n\t\t\tinput: `if p.A {\n\t{ \"A\" }\n} else if p.B {\n\t{ \"B\" }\n}`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.A`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"A\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 1, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 15, Line: 1, Col: 6},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tElseIfs: []ElseIfExpression{\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.B`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 28, Line: 2, Col: 10},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 31, Line: 2, Col: 13},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 34,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 37, Line: 3, Col: 3},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 40, Line: 3, Col: 6},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 18, Line: 2, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 43, Line: 4, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 44, Line: 4, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: else if, else if\",\n\t\t\tinput: `if p.A {\n\t{ \"A\" }\n} else if p.B {\n\t{ \"B\" }\n} else if p.C {\n\t{ \"C\" }\n}`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.A`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"A\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 1, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 15, Line: 1, Col: 6},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tElseIfs: []ElseIfExpression{\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.B`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 28, Line: 2, Col: 10},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 31, Line: 2, Col: 13},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 34,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 37, Line: 3, Col: 3},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 40, Line: 3, Col: 6},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 18, Line: 2, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 43, Line: 4, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.C`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 53, Line: 4, Col: 10},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 56, Line: 4, Col: 13},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 59,\n\t\t\t\t\t\t\t\t\tLine:  5,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 60,\n\t\t\t\t\t\t\t\t\tLine:  5,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"C\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 62, Line: 5, Col: 3},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 65, Line: 5, Col: 6},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 43, Line: 4, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 68, Line: 6, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 69, Line: 6, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: else if, else if, else\",\n\t\t\tinput: `if p.A {\n\t{ \"A\" }\n} else if p.B {\n\t{ \"B\" }\n} else if p.C {\n\t{ \"C\" }\n} else {\n\t{ \"D\" }\n}`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.A`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 3, Line: 0, Col: 3},\n\t\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 10,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"A\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 1, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 15, Line: 1, Col: 6},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tElseIfs: []ElseIfExpression{\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.B`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 28, Line: 2, Col: 10},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 31, Line: 2, Col: 13},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 34,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 37, Line: 3, Col: 3},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 40, Line: 3, Col: 6},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 18, Line: 2, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 43, Line: 4, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.C`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 53, Line: 4, Col: 10},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 56, Line: 4, Col: 13},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 59,\n\t\t\t\t\t\t\t\t\tLine:  5,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 60,\n\t\t\t\t\t\t\t\t\tLine:  5,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"C\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 62, Line: 5, Col: 3},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 65, Line: 5, Col: 6},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 43, Line: 4, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 68, Line: 6, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tElse: []Node{\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"D\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 80, Line: 7, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 83, Line: 7, Col: 6},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 87, Line: 8, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"if: else with comment and indentation\",\n\t\t\tinput: `if p.A {\n\t\t// this is a comment\n\t} else {\n\t\t{ \"B\" }\n\t}`,\n\t\t\texpected: &IfExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `p.A`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 3,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tThen: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\"},\n\t\t\t\t\t&GoComment{\n\t\t\t\t\t\tContents:  \" this is a comment\",\n\t\t\t\t\t\tMultiline: false,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 11, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 31, Line: 1, Col: 22},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 31,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   22,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 33,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\\t\"},\n\t\t\t\t},\n\t\t\t\tElse: []Node{\n\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 46,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 49,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 54, Line: 4, Col: 2},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, matched, err := ifExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIncompleteIf(t *testing.T) {\n\tt.Run(\"no opening brace\", func(t *testing.T) {\n\t\tinput := parse.NewInput(`if a tree falls in the woods`)\n\t\t_, _, err := ifExpression.Parse(input)\n\t\tif err == nil {\n\t\t\tt.Fatal(\"expected an error, got nil\")\n\t\t}\n\t\tpe, isParseError := err.(parse.ParseError)\n\t\tif !isParseError {\n\t\t\tt.Fatalf(\"expected a parse error, got %T\", err)\n\t\t}\n\t\tif pe.Msg != \"if: \"+unterminatedMissingCurly {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif pe.Pos.Line != 0 {\n\t\t\tt.Fatalf(\"unexpected line: %d\", pe.Pos.Line)\n\t\t}\n\t})\n\tt.Run(\"capitalised If\", func(t *testing.T) {\n\t\tinput := parse.NewInput(`If a tree falls in the woods`)\n\t\t_, matched, err := ifExpression.Parse(input)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif matched {\n\t\t\tt.Fatal(\"expected a non match\")\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "parser/v2/packageparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\n// Package.\nvar pkg = parse.Func(func(pi *parse.Input) (pkg Package, ok bool, err error) {\n\tstart := pi.Position()\n\n\t// Package prefix.\n\tif _, ok, err = parse.String(\"package \").Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Once we have the prefix, it's an expression until the end of the line.\n\tvar exp string\n\tif exp, ok, err = stringUntilNewLine.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"package literal not terminated\", pi.Position())\n\t\treturn\n\t}\n\tif len(exp) == 0 {\n\t\tok = false\n\t\terr = parse.Error(\"package literal not terminated\", start)\n\t\treturn\n\t}\n\n\t// Success!\n\tpkg.Expression = NewExpression(\"package \"+exp, start, pi.Position())\n\n\treturn pkg, true, nil\n})\n"
  },
  {
    "path": "parser/v2/packageparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestPackageParserErrors(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected parse.ParseError\n\t}{\n\t\t{\n\t\t\tname:  \"unterminated package\",\n\t\t\tinput: \"package \",\n\t\t\texpected: parse.Error(\n\t\t\t\t\"package literal not terminated\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 8,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   8,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname:  \"unterminated package, new line\",\n\t\t\tinput: \"package \\n\",\n\t\t\texpected: parse.Error(\n\t\t\t\t\"package literal not terminated\",\n\t\t\t\tparse.Position{\n\t\t\t\t\tIndex: 0,\n\t\t\t\t\tLine:  0,\n\t\t\t\t\tCol:   0,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tpi := parse.NewInput(tt.input)\n\t\t\t_, ok, err := pkg.Parse(pi)\n\t\t\tif ok {\n\t\t\t\tt.Errorf(\"expected parsing to fail, but it succeeded\")\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, err); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestPackageParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected any\n\t}{\n\t\t{\n\t\t\tname:  \"package: standard\",\n\t\t\tinput: \"package parser\\n\",\n\t\t\texpected: Package{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"package parser\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 0,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, ok, err := pkg.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/parser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\n// ) {\nvar expressionFuncEnd = parse.All(parse.Rune(')'), openBraceWithOptionalPadding)\n\n// Template\n\nvar template = parse.Func(func(pi *parse.Input) (r *HTMLTemplate, matched bool, err error) {\n\tstart := pi.Position()\n\n\t// templ FuncName(p Person, other Other) {\n\tvar te templateExpression\n\tif te, matched, err = templateExpressionParser.Parse(pi); err != nil || !matched {\n\t\treturn r, matched, err\n\t}\n\tr = &HTMLTemplate{\n\t\tExpression: te.Expression,\n\t}\n\tdefer func() {\n\t\tr.Range = NewRange(start, pi.Position())\n\t}()\n\n\t// Once we're in a template, we should expect some template whitespace, if/switch/for,\n\t// or node string expressions etc.\n\tvar nodes Nodes\n\tnodes, matched, err = newTemplateNodeParser(closeBraceWithOptionalPadding, \"template closing brace\").Parse(pi)\n\tif err != nil {\n\t\t// The LSP wants as many nodes as possible, so even though there was an error,\n\t\t// we probably have some valid nodes that the LSP can use.\n\t\tr.Children = nodes.Nodes\n\t\treturn r, true, err\n\t}\n\tif !matched {\n\t\treturn r, true, parse.Error(\"templ: expected nodes in templ body, but found none\", pi.Position())\n\t}\n\tr.Children = nodes.Nodes\n\n\t// Eat any whitespace.\n\t_, _, err = parse.OptionalWhitespace.Parse(pi)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// Try for }\n\tif _, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !matched {\n\t\terr = parse.Error(\"template: missing closing brace\", pi.Position())\n\t\treturn\n\t}\n\n\treturn r, true, nil\n})\n"
  },
  {
    "path": "parser/v2/raw.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/a-h/parse\"\n)\n\nvar styleElement = rawElementParser{\n\tname: \"style\",\n}\n\ntype rawElementParser struct {\n\tname string\n}\n\nfunc (p rawElementParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// <\n\tif _, ok, err = lt.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Element name.\n\te := &RawElement{}\n\tif e.Name, ok, err = elementNameParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\tif e.Name != p.name {\n\t\tpi.Seek(start)\n\t\tok = false\n\t\treturn\n\t}\n\n\tif e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Optional whitespace.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// >\n\tif _, ok, err = gt.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn\n\t}\n\n\t// Once we've got an open tag, parse anything until the end tag as the tag contents.\n\t// It's going to be rendered out raw.\n\tend := parse.All(parse.String(\"</\"), parse.String(p.name), parse.String(\">\"))\n\tif e.Contents, ok, err = parse.StringUntil(end).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(fmt.Sprintf(\"<%s>: expected end tag not present\", e.Name), pi.Position())\n\t\treturn\n\t}\n\t// Cut the end element.\n\t_, _, _ = end.Parse(pi)\n\n\te.Range = NewRange(pi.PositionAt(start), pi.Position())\n\treturn e, true, nil\n}\n"
  },
  {
    "path": "parser/v2/raw_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nvar ignoredContent = `{\n\tfjkjkl: 123,\n\t{{\n}`\n\nfunc TestRawElementParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *RawElement\n\t}{\n\t\t{\n\t\t\tname:  \"style tag\",\n\t\t\tinput: `<style type=\"text/css\">contents</style>`,\n\t\t\texpected: &RawElement{\n\t\t\t\tName: \"style\",\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"text/css\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"type\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\tTo:   Position{Index: 22, Line: 0, Col: 22},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContents: \"contents\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 39, Line: 0, Col: 39},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"style tag containing mismatched braces\",\n\t\t\tinput: `<style type=\"text/css\">` + ignoredContent + \"</style>\",\n\t\t\texpected: &RawElement{\n\t\t\t\tName: \"style\",\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"text/css\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"type\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 7, Line: 0, Col: 7},\n\t\t\t\t\t\t\tTo:   Position{Index: 22, Line: 0, Col: 22},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContents: ignoredContent,\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 52, Line: 3, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, ok, err := rawElements.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestRawElementParserIsNotGreedy(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected RawElement\n\t}{\n\t\t{\n\t\t\tname:  \"styles tag\",\n\t\t\tinput: `<styles></styles>`,\n\t\t},\n\t\t{\n\t\t\tname:  \"scripts tag\",\n\t\t\tinput: `<scripts></scripts>`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, ok, err := rawElements.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif ok {\n\t\t\t\tt.Fatalf(\"unexpected success for input %q\", tt.input)\n\t\t\t}\n\t\t\tif actual != nil {\n\t\t\t\tt.Fatalf(\"expected nil Node got %v\", actual)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/scriptparser.go",
    "content": "package parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/a-h/parse\"\n)\n\nvar scriptElement = scriptElementParser{}\n\ntype jsQuote string\n\nconst (\n\tjsQuoteNone     jsQuote = \"\"\n\tjsQuoteSingle   jsQuote = `'`\n\tjsQuoteDouble   jsQuote = `\"`\n\tjsQuoteBacktick jsQuote = \"`\"\n)\n\ntype scriptElementParser struct{}\n\nfunc (p scriptElementParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {\n\tstart := pi.Index()\n\n\t// <\n\tif _, ok, err = lt.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Element name.\n\te := &ScriptElement{}\n\tvar name string\n\tif name, ok, err = elementNameParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn n, false, err\n\t}\n\n\tif name != \"script\" {\n\t\tpi.Seek(start)\n\t\treturn n, false, nil\n\t}\n\n\tif e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn n, false, err\n\t}\n\n\t// Optional whitespace.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\tpi.Seek(start)\n\t\treturn n, false, err\n\t}\n\n\t// >\n\tif _, ok, err = gt.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start)\n\t\treturn n, false, parse.Error(\"<script>: unclosed element - missing '>'\", pi.Position())\n\t}\n\n\t// If there's a type attribute and it's not a JS attribute (e.g. text/javascript), we need to parse the contents as raw text.\n\tif !hasJavaScriptType(e.Attributes) {\n\t\tvar contents string\n\t\tif contents, ok, err = parse.StringUntil(jsEndTag).Parse(pi); err != nil || !ok {\n\t\t\treturn e, true, parse.Error(\"<script>: expected end tag not present\", pi.Position())\n\t\t}\n\t\te.Contents = append(e.Contents, NewScriptContentsScriptCode(contents))\n\n\t\t// Cut the end element.\n\t\t_, _, _ = jsEndTag.Parse(pi)\n\n\t\treturn e, true, nil\n\t}\n\n\t// Parse the contents, we should get script text or Go expressions up until the closing tag.\n\tvar sb strings.Builder\n\tvar stringLiteralDelimiter jsQuote\n\nloop:\n\tfor {\n\t\t// Read and decide whether we're we've hit a:\n\t\t//  - {{ - Start of a Go expression, read the contents with the `goCode` function.\n\t\t//  - </script> - End of the script, break out of the loop.\n\t\t//  - ' - Start of a single quoted string.\n\t\t//  - \" - Start of a double quoted string.\n\t\t//  - ` - Start of a backtick quoted string.\n\t\t//  - // - Start of a single line comment - can read to the end of the line without parsing.\n\t\t//  - /* - Start of a multi-line comment - can read to the end of the comment without parsing.\n\t\t//  - \\ - Start of an escape sequence, we can just take the value.\n\t\t//  - Anything else - Add it to the script.\n\n\t\t_, ok, err = jsEndTag.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tif ok {\n\t\t\t// We've reached the end of the script.\n\t\t\tbreak loop\n\t\t}\n\n\t\t_, ok, err = endTagStart.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tif ok {\n\t\t\treturn nil, false, parse.Error(\"<script>: invalid end tag, expected </script> not found\", pi.Position())\n\t\t}\n\n\t\t// Try for a Go code expression, i.e. {{ goCode }}.\n\t\tcode, ok, err := goCodeInJavaScript.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tif ok {\n\t\t\te.Contents = append(e.Contents, NewScriptContentsGo(code.(*GoCode), stringLiteralDelimiter != jsQuoteNone))\n\t\t\tcontinue loop\n\t\t}\n\n\t\t// Try for a comment.\n\t\tcomment, ok, err := jsComment.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn nil, false, err\n\t\t}\n\t\tif ok {\n\t\t\te.Contents = append(e.Contents, NewScriptContentsScriptCode(comment))\n\t\t\tcontinue loop\n\t\t}\n\n\t\t// Read JavaScript characters.\n\tcharLoop:\n\t\tfor {\n\t\t\tbefore := pi.Index()\n\n\t\t\t// If we're outside of a string literal, check for a regexp literal.\n\t\t\t// Check for a regular expression literal.\n\t\t\tif stringLiteralDelimiter == jsQuoteNone {\n\t\t\t\tr, ok, err := regexpLiteral.Parse(pi)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, false, err\n\t\t\t\t}\n\t\t\t\tif ok {\n\t\t\t\t\tsb.WriteString(r)\n\t\t\t\t\tcontinue charLoop\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check for EOF.\n\t\t\tif _, ok, _ = parse.EOF[string]().Parse(pi); ok {\n\t\t\t\treturn nil, false, parse.Error(\"script: unclosed <script> element\", pi.Position())\n\t\t\t}\n\n\t\t\t// Check for a character.\n\t\t\tc, ok, err := jsCharacter.Parse(pi)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, false, err\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\treturn nil, false, parse.Error(\"script: expected to parse a character, but didn't\", pi.Position())\n\t\t\t}\n\t\t\tif c == string(jsQuoteDouble) || c == string(jsQuoteSingle) || c == string(jsQuoteBacktick) {\n\t\t\t\t// Start or exit a string literal.\n\t\t\t\tif stringLiteralDelimiter == jsQuoteNone {\n\t\t\t\t\tstringLiteralDelimiter = jsQuote(c)\n\t\t\t\t} else if stringLiteralDelimiter == jsQuote(c) {\n\t\t\t\t\tstringLiteralDelimiter = jsQuoteNone\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpeeked, peekOK := pi.Peek(1)\n\t\t\tisEOF := !peekOK\n\t\t\tpeeked = c + peeked\n\t\t\tbreakForGo := peeked == \"{{\"\n\t\t\tbreakForHTML := stringLiteralDelimiter == jsQuoteNone && peeked == \"</\"\n\t\t\tbreakForComment := stringLiteralDelimiter == jsQuoteNone && (peeked == \"//\" || peeked == \"/*\")\n\t\t\tif isEOF || breakForGo || breakForHTML || breakForComment {\n\t\t\t\tif sb.Len() > 0 {\n\t\t\t\t\te.Contents = append(e.Contents, NewScriptContentsScriptCode(sb.String()))\n\t\t\t\t\tsb.Reset()\n\t\t\t\t}\n\t\t\t\tif isEOF {\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t\tpi.Seek(before)\n\t\t\t\tcontinue loop\n\t\t\t}\n\n\t\t\tsb.WriteString(c)\n\t\t}\n\t}\n\n\te.Range = NewRange(pi.PositionAt(start), pi.Position())\n\treturn e, true, nil\n}\n\nvar javaScriptTypeAttributeValues = []string{\n\t\"\", // If the type is not set, it is JavaScript.\n\t\"text/javascript\",\n\t\"javascript\", // Obsolete, but still used.\n\t\"module\",\n}\n\nfunc hasJavaScriptType(attrs []Attribute) bool {\n\tfor _, attr := range attrs {\n\t\tca, isCA := attr.(*ConstantAttribute)\n\t\tif !isCA {\n\t\t\tcontinue\n\t\t}\n\t\tcaKey, isCAKey := ca.Key.(ConstantAttributeKey)\n\t\tif !isCAKey {\n\t\t\tcontinue\n\t\t}\n\t\tif !strings.EqualFold(caKey.Name, \"type\") {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, v := range javaScriptTypeAttributeValues {\n\t\t\tif strings.EqualFold(ca.Value, v) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\t// If there's a type attribute but the value doesn't match any\n\t\t// known JavaScript type, it's not JavaScript.\n\t\treturn false\n\t}\n\t// If there's no type attribute, it's JavaScript.\n\treturn true\n}\n\nvar (\n\tjsEndTag    = parse.String(\"</script>\")\n\tendTagStart = parse.String(\"</\")\n)\n\nvar jsCharacter = parse.Any(jsEscapedCharacter, parse.AnyRune)\n\n// \\uXXXX\tUnicode code point escape\t'\\u0061' = 'a'\nvar (\n\thexDigit        = parse.Any(parse.ZeroToNine, parse.RuneIn(\"abcdef\"), parse.RuneIn(\"ABCDEF\"))\n\tjsUnicodeEscape = parse.StringFrom(parse.String(\"\\\\u\"), hexDigit, hexDigit, hexDigit, hexDigit)\n)\n\n// \\u{X...}\tES6+ extended Unicode escape\t'\\u{1F600}' = '😀'\nvar jsExtendedUnicodeEscape = parse.StringFrom(parse.String(\"\\\\u{\"), hexDigit, parse.StringFrom(parse.AtLeast(1, parse.ZeroOrMore(hexDigit))), parse.String(\"}\"))\n\n// \\xXX\tHex code (2-digit)\t'\\x41' = 'A'\nvar jsHexEscape = parse.StringFrom(parse.String(\"\\\\x\"), hexDigit, hexDigit)\n\n// \\x Backslash escape\t'\\\\' = '\\'\nvar jsBackslashEscape = parse.StringFrom(parse.String(\"\\\\\"), parse.AnyRune)\n\n// All escapes.\nvar jsEscapedCharacter = parse.Any(jsBackslashEscape, jsUnicodeEscape, jsHexEscape, jsExtendedUnicodeEscape)\n\nvar jsComment = parse.Any(jsSingleLineComment, jsMultiLineComment)\n\nvar (\n\tjsStartSingleLineComment = parse.String(\"//\")\n\tjsEndOfSingleLineComment = parse.StringFrom(parse.Or(parse.NewLine, parse.EOF[string]()))\n\tjsSingleLineComment      = parse.StringFrom(jsStartSingleLineComment, parse.StringUntil(jsEndOfSingleLineComment), jsEndOfSingleLineComment)\n)\n\nvar (\n\tjsStartMultiLineComment = parse.String(\"/*\")\n\tjsEndOfMultiLineComment = parse.StringFrom(parse.Or(parse.String(\"*/\"), parse.EOF[string]()))\n\tjsMultiLineComment      = parse.StringFrom(jsStartMultiLineComment, parse.StringUntil(jsEndOfMultiLineComment), jsEndOfMultiLineComment, parse.OptionalWhitespace)\n)\n\nvar regexpLiteral = parse.Func(func(in *parse.Input) (regexp string, ok bool, err error) {\n\tstartIndex := in.Index()\n\n\t// Take the initial '/'.\n\ts, ok := in.Take(1)\n\tif !ok || s != \"/\" {\n\t\tin.Seek(startIndex)\n\t\treturn \"\", false, nil\n\t}\n\t// Peek the next char. If it's also a '/', then this is not a regex literal, but the start of a comment.\n\tp, ok := in.Peek(1)\n\tif !ok || p == \"/\" {\n\t\tin.Seek(startIndex)\n\t\treturn \"\", false, nil\n\t}\n\tvar literal strings.Builder\n\tliteral.WriteString(s)\n\n\tvar inClass, escaped bool\n\n\tfor {\n\t\ts, ok := in.Take(1)\n\t\tif !ok {\n\t\t\t// Restore position if no closing '/'.\n\t\t\tin.Seek(startIndex)\n\t\t\treturn \"\", false, nil\n\t\t}\n\n\t\tliteral.WriteString(s)\n\n\t\tif escaped {\n\t\t\tescaped = false\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch s {\n\t\tcase \"\\n\", \"\\r\":\n\t\t\t// Newline in a regex is not allowed, so we restore the position and return false.\n\t\t\tin.Seek(startIndex)\n\t\t\treturn \"\", false, nil\n\t\tcase \"\\\\\":\n\t\t\tescaped = true\n\t\tcase \"[\":\n\t\t\tinClass = true\n\t\tcase \"]\":\n\t\t\tinClass = false\n\t\tcase \"/\":\n\t\t\tif !inClass {\n\t\t\t\t// We've reached the end of the regex, but there may be flags after it.\n\t\t\t\t// Read flags until we hit a non-flag character.\n\t\t\t\tflags, ok, err := regexpFlags.Parse(in)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn \"\", false, err\n\t\t\t\t}\n\t\t\t\tif ok {\n\t\t\t\t\tliteral.WriteString(flags)\n\t\t\t\t}\n\t\t\t\toutput := literal.String()\n\t\t\t\tif strings.Contains(output, \"{{\") && strings.Contains(output, \"}}\") {\n\t\t\t\t\t// If the regex contains a Go expression, don't treat it as a regex literal.\n\t\t\t\t\tin.Seek(startIndex)\n\t\t\t\t\treturn \"\", false, nil\n\t\t\t\t}\n\t\t\t\treturn output, true, nil\n\t\t\t}\n\t\t}\n\t}\n})\n\nvar regexpFlags = parse.StringFrom(parse.Repeat(0, 5, parse.RuneIn(\"gimuy\")))\n"
  },
  {
    "path": "parser/v2/scriptparser_test.go",
    "content": "package parser\n\nimport (\n\t\"bytes\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t_ \"embed\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"golang.org/x/tools/txtar\"\n)\n\nfunc TestScriptElementParserPlain(t *testing.T) {\n\tfiles, _ := filepath.Glob(\"scriptparsertestdata/*.txt\")\n\tif len(files) == 0 {\n\t\tt.Errorf(\"no test files found\")\n\t}\n\tfor _, file := range files {\n\t\tt.Run(filepath.Base(file), func(t *testing.T) {\n\t\t\ta, err := txtar.ParseFile(file)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif len(a.Files) != 2 {\n\t\t\t\tt.Fatalf(\"expected 2 files, got %d\", len(a.Files))\n\t\t\t}\n\n\t\t\tinput := parse.NewInput(clean(a.Files[0].Data))\n\t\t\tresult, ok, err := scriptElement.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\n\t\t\tse, isScriptElement := result.(*ScriptElement)\n\t\t\tif !isScriptElement {\n\t\t\t\tt.Fatalf(\"expected ScriptElement, got %T\", result)\n\t\t\t}\n\n\t\t\tvar actual strings.Builder\n\t\t\tfor _, content := range se.Contents {\n\t\t\t\tif content.GoCode != nil {\n\t\t\t\t\tt.Fatalf(\"expected plain text, got GoCode\")\n\t\t\t\t}\n\t\t\t\tif content.Value == nil {\n\t\t\t\t\tt.Fatalf(\"expected plain text, got nil\")\n\t\t\t\t}\n\t\t\t\tactual.WriteString(*content.Value)\n\t\t\t}\n\n\t\t\texpected := clean(a.Files[1].Data)\n\t\t\tif diff := cmp.Diff(string(expected), actual.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestScriptElementParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *ScriptElement\n\t}{\n\t\t{\n\t\t\tname:  \"no content\",\n\t\t\tinput: `<script></script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"vbscript\",\n\t\t\tinput: `<script type=\"vbscript\">dim x = 1</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\tValue: \"vbscript\",\n\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\tName: \"type\",\n\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\tTo:   Position{Index: 23, Line: 0, Col: 23},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"dim x = 1\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"go expression\",\n\t\t\tinput: `<script>{{ name }}</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 11, Line: 0, Col: 11},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, false),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 27, Line: 0, Col: 27},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"go expression with explicit type\",\n\t\t\tinput: `<script type=\"text/javascript\">{{ name }}</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tAttributes: []Attribute{&ConstantAttribute{\n\t\t\t\t\tValue: \"text/javascript\",\n\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\tName: \"type\", NameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\tTo:   Position{Index: 30, Line: 0, Col: 30},\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 34, Line: 0, Col: 34},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 38, Line: 0, Col: 38},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, false),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 50, Line: 0, Col: 50},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"go expression with module type\",\n\t\t\tinput: `<script type=\"module\">{{ name }}</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tAttributes: []Attribute{&ConstantAttribute{\n\t\t\t\t\tValue: \"module\",\n\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\tName: \"type\", NameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 25, Line: 0, Col: 25},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 29, Line: 0, Col: 29},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, false),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 41, Line: 0, Col: 41},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"go expression with javascript type\",\n\t\t\tinput: `<script type=\"javascript\">{{ name }}</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tAttributes: []Attribute{&ConstantAttribute{\n\t\t\t\t\tValue: \"javascript\",\n\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\tName: \"type\", NameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\tTo:   Position{Index: 25, Line: 0, Col: 25},\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 29, Line: 0, Col: 29},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 33, Line: 0, Col: 33},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, false),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 45, Line: 0, Col: 45},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"go expression - multiline 1\",\n\t\t\tinput: `<script>\n{{ name }}\n</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\n\"),\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 12, Line: 1, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 16, Line: 1, Col: 7},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t}, false),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 29, Line: 2, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"go expression in single quoted string\",\n\t\t\tinput: `<script>var x = '{{ name }}';</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"var x = '\"),\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 24, Line: 0, Col: 24},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, true),\n\t\t\t\t\tNewScriptContentsScriptCode(\"';\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 38, Line: 0, Col: 38},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"go expression in double quoted string\",\n\t\t\tinput: `<script>var x = \"{{ name }}\";</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"var x = \\\"\"),\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 24, Line: 0, Col: 24},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, true),\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\\";\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 38, Line: 0, Col: 38},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"go expression in double quoted multiline string\",\n\t\t\tinput: `<script>var x = \"This is a test \\\n{{ name }} \\\nto see if it works\";</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"var x = \\\"This is a test \\\\\\n\"),\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 37, Line: 1, Col: 3},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 41, Line: 1, Col: 7},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceHorizontal,\n\t\t\t\t\t}, true),\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\\\\\nto see if it works\\\";\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 76, Line: 2, Col: 29},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"go expression in backtick quoted string\",\n\t\t\tinput: `<script>var x = ` + \"`\" + \"{{ name }}\" + \"`\" + `;</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"var x = `\"),\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"name\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 20, Line: 0, Col: 20},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 24, Line: 0, Col: 24},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, true),\n\t\t\t\t\tNewScriptContentsScriptCode(\"`;\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 38, Line: 0, Col: 38},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"single line commented out go expressions are ignored\",\n\t\t\tinput: `<script>\n// {{ name }}\n</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\n\"),\n\t\t\t\t\tNewScriptContentsScriptCode(\"// {{ name }}\\n\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 32, Line: 2, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"single line comments after expressions are allowed\",\n\t\t\tinput: `<script>\nconst category = path.split('/')[2]; // example comment\n</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\nconst category = path.split('/')[2]; \"),\n\t\t\t\t\tNewScriptContentsScriptCode(\"// example comment\\n\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 74, Line: 2, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiline commented out go expressions are ignored\",\n\t\t\tinput: `<script>\n/* There's some content\n{{ name }}\nbut it's commented out */\n</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\n\"),\n\t\t\t\t\tNewScriptContentsScriptCode(\"/* There's some content\\n{{ name }}\\nbut it's commented out */\\n\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 79, Line: 4, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"non js content is parsed raw\",\n\t\t\tinput: `<script type=\"text/hyperscript\">\nset tier_1 to #tier-1's value\n</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tAttributes: []Attribute{&ConstantAttribute{\n\t\t\t\t\tValue: \"text/hyperscript\",\n\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\tName: \"type\", NameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 8, Line: 0, Col: 8},\n\t\t\t\t\t\tTo:   Position{Index: 31, Line: 0, Col: 31},\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\nset tier_1 to #tier-1's value\\n\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"regexp expressions\",\n\t\t\tinput: `<script>\nconst result = call(1000 / 10, {{ data }}, 1000 / 10);\n</script>`,\n\t\t\texpected: &ScriptElement{\n\t\t\t\tContents: []ScriptContents{\n\t\t\t\t\tNewScriptContentsScriptCode(\"\\nconst result = call(1000 / 10, \"),\n\t\t\t\t\tNewScriptContentsGo(&GoCode{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"data\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 43, Line: 1, Col: 34},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 47, Line: 1, Col: 38},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}, false),\n\t\t\t\t\tNewScriptContentsScriptCode(\", 1000 / 10);\\n\"),\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 73, Line: 2, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := scriptElement.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"failed to parse at %d\", input.Index())\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, result); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestScriptElementRegexpParser(t *testing.T) {\n\ttests := []struct {\n\t\tname       string\n\t\tinput      string\n\t\texpected   string\n\t\texpectedOK bool\n\t}{\n\t\t{\n\t\t\tname:       \"no content is considered to be a comment\",\n\t\t\tinput:      `//`,\n\t\t\texpectedOK: false,\n\t\t},\n\t\t{\n\t\t\tname:       \"must not be multiline\",\n\t\t\tinput:      \"/div>\\n</div>\",\n\t\t\texpectedOK: false,\n\t\t},\n\t\t{\n\t\t\tname:       \"match a single char\",\n\t\t\tinput:      `/a/`,\n\t\t\texpected:   `/a/`,\n\t\t\texpectedOK: true,\n\t\t},\n\t\t{\n\t\t\tname:       \"match a simple regex\",\n\t\t\tinput:      `/a|b/`,\n\t\t\texpected:   `/a|b/`,\n\t\t\texpectedOK: true,\n\t\t},\n\t\t{\n\t\t\tname:       \"match a complex regex\",\n\t\t\tinput:      `/a(b|c)*d{2,4}/`,\n\t\t\texpected:   `/a(b|c)*d{2,4}/`,\n\t\t\texpectedOK: true,\n\t\t},\n\t\t{\n\t\t\tname:       \"match a regex with flags\",\n\t\t\tinput:      `/a/i`,\n\t\t\texpected:   `/a/i`,\n\t\t\texpectedOK: true,\n\t\t},\n\t\t{\n\t\t\tname:       \"match a regex with multiple flags\",\n\t\t\tinput:      `/a/gmi`,\n\t\t\texpected:   `/a/gmi`,\n\t\t\texpectedOK: true,\n\t\t},\n\t\t{\n\t\t\tname:       \"escaped slashes\",\n\t\t\tinput:      `/a\\/b\\/c/`,\n\t\t\texpected:   `/a\\/b\\/c/`,\n\t\t\texpectedOK: true,\n\t\t},\n\t\t{\n\t\t\tname:       \"no match: missing closing slash\",\n\t\t\tinput:      `/a|b`,\n\t\t\texpected:   \"\",\n\t\t\texpectedOK: false,\n\t\t},\n\t\t{\n\t\t\tname:       \"no match: missing opening slash\",\n\t\t\tinput:      `a|b/`,\n\t\t\texpected:   \"\",\n\t\t\texpectedOK: false,\n\t\t},\n\t\t{\n\t\t\tname:       \"must not contain interpolated go expressions\",\n\t\t\tinput:      `/a{{ b }}/`,\n\t\t\texpected:   \"\",\n\t\t\texpectedOK: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tresult, ok, err := regexpLiteral.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"parser error: %v\", err)\n\t\t\t}\n\t\t\tif ok != tt.expectedOK {\n\t\t\t\tt.Fatalf(\"expected ok to be %v, got %v\", tt.expectedOK, ok)\n\t\t\t}\n\t\t\tif result != tt.expected {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", tt.expected, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc FuzzScriptParser(f *testing.F) {\n\tfiles, _ := filepath.Glob(\"scriptparsertestdata/*.txt\")\n\tif len(files) == 0 {\n\t\tf.Errorf(\"no test files found\")\n\t}\n\tfor _, file := range files {\n\t\ta, err := txtar.ParseFile(file)\n\t\tif err != nil {\n\t\t\tf.Fatal(err)\n\t\t}\n\t\tif len(a.Files) != 2 {\n\t\t\tf.Fatalf(\"expected 2 files, got %d\", len(a.Files))\n\t\t}\n\t\tf.Add(clean(a.Files[0].Data))\n\t}\n\n\tf.Fuzz(func(t *testing.T, input string) {\n\t\t_, _, _ = scriptElement.Parse(parse.NewInput(input))\n\t})\n}\n\nfunc clean(b []byte) string {\n\tb = bytes.ReplaceAll(b, []byte(\"$\\n\"), []byte(\"\\n\"))\n\tb = bytes.TrimSuffix(b, []byte(\"\\n\"))\n\treturn string(b)\n}\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/backtickquote.txt",
    "content": "-- in --\n<script>\nwindow.alert(`This is 'single quoted' and this is \"double quoted\"`);\n</script>\n-- out --\n\nwindow.alert(`This is 'single quoted' and this is \"double quoted\"`);\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/backtickquote_apostrophe.txt",
    "content": "-- in --\n<script>\nwindow.alert(`You can use isn't and other text`);\n</script>\n-- out --\n\nwindow.alert(`You can use isn't and other text`);\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/doublequote.txt",
    "content": "-- in --\n<script>\nwindow.alert(\"This is 'quoted'\");\n</script>\n-- out --\n\nwindow.alert(\"This is 'quoted'\");\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/doublequote_apostrophe.txt",
    "content": "-- in --\n<script>\nwindow.alert(\"You can use isn't and other text\");\n</script>\n-- out --\n\nwindow.alert(\"You can use isn't and other text\");\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/escapechars.txt",
    "content": "-- in --\n<script>\nconst singleQuotedBackslashEscape = '\\x61'; // a\nconst singleQuotedHexEscape = '\\x61';\nconst singleQuotedUnicodeEscape = '\\u0061';\nconst singleQuotedExtendedUnicodeEscape = '\\u{61}';\n\nconst doubleQuotedBackslashEscape = \"\\x61\"; // a\nconst doubleQuotedHexEscape = \"\\x61\";\nconst doubleQuotedUnicodeEscape = \"\\u0061\";\nconst doubleQuotedExtendedUnicodeEscape = \"\\u{61}\";\n\nconst backtickQuotedBackslashEscape = `\\x61`; // a\nconst backtickQuotedHexEscape = `\\x61`;\nconst backtickQuotedUnicodeEscape = `\\u0061`;\nconst backtickQuotedExtendedUnicodeEscape = `\\u{61}`;\n</script>\n-- out --\n\nconst singleQuotedBackslashEscape = '\\x61'; // a\nconst singleQuotedHexEscape = '\\x61';\nconst singleQuotedUnicodeEscape = '\\u0061';\nconst singleQuotedExtendedUnicodeEscape = '\\u{61}';\n\nconst doubleQuotedBackslashEscape = \"\\x61\"; // a\nconst doubleQuotedHexEscape = \"\\x61\";\nconst doubleQuotedUnicodeEscape = \"\\u0061\";\nconst doubleQuotedExtendedUnicodeEscape = \"\\u{61}\";\n\nconst backtickQuotedBackslashEscape = `\\x61`; // a\nconst backtickQuotedHexEscape = `\\x61`;\nconst backtickQuotedUnicodeEscape = `\\u0061`;\nconst backtickQuotedExtendedUnicodeEscape = `\\u{61}`;\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/non_js_script.txt",
    "content": "-- in --\n<script type=\"text/hyperscript\">\nset foo to #foo's value\n</script>\n-- out --\n\nset foo to #foo's value\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/regexp_literal.txt",
    "content": "-- in --\n<script>\nconst regex = /data-client-id=\"([^\"]+)\"/;\nconst clientIdMatch = evt.detail.message.match(regex);\n</script>\n-- out --\n\nconst regex = /data-client-id=\"([^\"]+)\"/;\nconst clientIdMatch = evt.detail.message.match(regex);\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/showsuccessmessage.txt",
    "content": "-- in --\n<script>\n  function showSuccessMessage(responseText) {\n\t\t\tconst formResponse = document.getElementById('form-response');\n\t\t\tformResponse.innerHTML = `\n\t\t\t\t<div class=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded\">\n\t\t\t\t\t${responseText}\n\t\t\t\t</div>`;\n\t\t}\n</script>\n-- out --\n\n  function showSuccessMessage(responseText) {\n\t\t\tconst formResponse = document.getElementById('form-response');\n\t\t\tformResponse.innerHTML = `\n\t\t\t\t<div class=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded\">\n\t\t\t\t\t${responseText}\n\t\t\t\t</div>`;\n\t\t}\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/singlequote.txt",
    "content": "-- in --\n<script>\nwindow.alert('This is \"quoted\"');\n</script>\n-- out --\n\nwindow.alert('This is \"quoted\"');\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/singlequote_apostrophe.txt",
    "content": "-- in --\n<script>\nwindow.alert('An unclosed \" is allowed in single quotes');\n</script>\n-- out --\n\nwindow.alert('An unclosed \" is allowed in single quotes');\n\n"
  },
  {
    "path": "parser/v2/scriptparsertestdata/terminating_comment.txt",
    "content": "-- in --\n<script>\nconst category = path.split('/')[2]; // example comment\n</script>\n-- out --\n\nconst category = path.split('/')[2]; // example comment\n\n"
  },
  {
    "path": "parser/v2/scripttemplateparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\nvar scriptTemplateParser = parse.Func(func(pi *parse.Input) (r *ScriptTemplate, ok bool, err error) {\n\tstart := pi.Position()\n\n\t// Parse the name.\n\tvar se scriptExpression\n\tif se, ok, err = scriptExpressionParser.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start.Index)\n\t\treturn\n\t}\n\tr = &ScriptTemplate{\n\t\tName:       se.Name,\n\t\tParameters: se.Parameters,\n\t}\n\tdefer func() {\n\t\tr.Range = NewRange(start, pi.Position())\n\t}()\n\n\t// Read code expression.\n\tvar e Expression\n\tif e, ok, err = exp.Parse(pi); err != nil || !ok {\n\t\tpi.Seek(start.Index)\n\t\treturn\n\t}\n\tr.Value = e.Value\n\n\t// Try for }\n\tif _, ok, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"script template: missing closing brace\", pi.Position())\n\t\treturn\n\t}\n\n\treturn r, true, nil\n})\n\n// script Func() {\ntype scriptExpression struct {\n\tName       Expression\n\tParameters Expression\n}\n\nvar scriptExpressionNameParser = ExpressionOf(parse.StringFrom(\n\tparse.Letter,\n\tparse.StringFrom(parse.AtMost(1000, parse.Any(parse.Letter, parse.ZeroToNine))),\n))\n\nvar scriptExpressionParser = parse.Func(func(pi *parse.Input) (r scriptExpression, ok bool, err error) {\n\t// Check the prefix first.\n\tif _, ok, err = parse.String(\"script \").Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\n\t// Once we have the prefix, we must have a name and parameters.\n\t// Read the name of the function.\n\tif r.Name, ok, err = scriptExpressionNameParser.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"script expression: invalid name\", pi.Position())\n\t\treturn\n\t}\n\n\t// Eat the open bracket.\n\tif _, ok, err = openBracket.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"script expression: parameters missing open bracket\", pi.Position())\n\t\treturn\n\t}\n\n\t// Read the parameters.\n\t// p Person, other Other, t thing.Thing)\n\tif r.Parameters, ok, err = ExpressionOf(parse.StringUntil(closeBracket)).Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"script expression: parameters missing close bracket\", pi.Position())\n\t\treturn\n\t}\n\n\t// Eat \") {\".\n\tif _, ok, err = expressionFuncEnd.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"script expression: unterminated (missing ') {')\", pi.Position())\n\t\treturn\n\t}\n\n\t// Expect a newline.\n\tif _, ok, err = parse.NewLine.Parse(pi); err != nil || !ok {\n\t\terr = parse.Error(\"script expression: missing terminating newline\", pi.Position())\n\t\treturn\n\t}\n\n\treturn r, true, nil\n})\n"
  },
  {
    "path": "parser/v2/scripttemplateparser_test.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestScriptTemplateParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *ScriptTemplate\n\t}{\n\t\t{\n\t\t\tname: \"script: no parameters, no content\",\n\t\t\tinput: `script Name() {\n}`,\n\t\t\texpected: &ScriptTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 17, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tName: Expression{\n\t\t\t\t\tValue: \"Name\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tParameters: Expression{\n\t\t\t\t\tValue: \"\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"script: no spaces\",\n\t\t\tinput: `script Name(){\n}`,\n\t\t\texpected: &ScriptTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 16, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tName: Expression{\n\t\t\t\t\tValue: \"Name\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tParameters: Expression{\n\t\t\t\t\tValue: \"\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"script: containing a JS variable\",\n\t\t\tinput: `script Name() {\nvar x = \"x\";\n}`,\n\t\t\texpected: &ScriptTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 30, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tName: Expression{\n\t\t\t\t\tValue: \"Name\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tParameters: Expression{\n\t\t\t\t\tValue: \"\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tValue: `var x = \"x\";` + \"\\n\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"script: single argument\",\n\t\t\tinput: `script Name(value string) {\nconsole.log(value);\n}`,\n\t\t\texpected: &ScriptTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 49, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tName: Expression{\n\t\t\t\t\tValue: \"Name\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tParameters: Expression{\n\t\t\t\t\tValue: \"value string\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 24,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   24,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tValue: `console.log(value);` + \"\\n\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"script: comment with single quote\",\n\t\t\tinput: `script Name() {\n\t//'\n}`,\n\t\t\texpected: &ScriptTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 22, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tName: Expression{\n\t\t\t\t\tValue: \"Name\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tParameters: Expression{\n\t\t\t\t\tValue: \"\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tValue: `\t//'` + \"\\n\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"script: empty assignment\",\n\t\t\tinput: `script Name() {\n  let x = '';\n}`,\n\t\t\texpected: &ScriptTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 31, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tName: Expression{\n\t\t\t\t\tValue: \"Name\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 11,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tValue: `  let x = '';` + \"\\n\",\n\t\t\t\tParameters: Expression{\n\t\t\t\t\tValue: \"\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tsuffixes := []string{\"\", \" Trailing '\", ` Trailing \"`, \"\\n// More content.\"}\n\t\tfor i, suffix := range suffixes {\n\t\t\tt.Run(fmt.Sprintf(\"%s_%d\", tt.name, i), func(t *testing.T) {\n\t\t\t\tinput := parse.NewInput(tt.input + suffix)\n\t\t\t\tactual, ok, err := scriptTemplateParser.Parse(input)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t\t}\n\t\t\t\tif !ok {\n\t\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t\t}\n\t\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\t\tt.Error(diff)\n\t\t\t\t}\n\t\t\t\tactualSuffix, _ := input.Peek(-1)\n\t\t\t\tif diff := cmp.Diff(suffix, actualSuffix); diff != \"\" {\n\t\t\t\t\tt.Error(\"unexpected suffix\")\n\t\t\t\t\tt.Error(diff)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "parser/v2/sourcemap.go",
    "content": "package parser\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// NewSourceMap creates a new lookup to map templ source code to items in the\n// parsed template.\nfunc NewSourceMap() *SourceMap {\n\treturn &SourceMap{\n\t\tSourceLinesToTarget:       make(map[uint32]map[uint32]Position),\n\t\tTargetLinesToSource:       make(map[uint32]map[uint32]Position),\n\t\tSourceSymbolRangeToTarget: make(map[uint32]map[uint32]Range),\n\t\tTargetSymbolRangeToSource: make(map[uint32]map[uint32]Range),\n\t}\n}\n\ntype SourceMap struct {\n\tExpressions               []string\n\tSourceLinesToTarget       map[uint32]map[uint32]Position\n\tTargetLinesToSource       map[uint32]map[uint32]Position\n\tSourceSymbolRangeToTarget map[uint32]map[uint32]Range\n\tTargetSymbolRangeToSource map[uint32]map[uint32]Range\n}\n\nfunc (sm *SourceMap) AddSymbolRange(src Range, tgt Range) {\n\tsm.SourceSymbolRangeToTarget[src.From.Line] = make(map[uint32]Range)\n\tsm.SourceSymbolRangeToTarget[src.From.Line][src.From.Col] = tgt\n\tsm.TargetSymbolRangeToSource[tgt.From.Line] = make(map[uint32]Range)\n\tsm.TargetSymbolRangeToSource[tgt.From.Line][tgt.From.Col] = src\n}\n\nfunc (sm *SourceMap) SymbolTargetRangeFromSource(line, col uint32) (tgt Range, ok bool) {\n\tlm, ok := sm.SourceSymbolRangeToTarget[line]\n\tif !ok {\n\t\treturn\n\t}\n\ttgt, ok = lm[col]\n\treturn\n}\n\nfunc (sm *SourceMap) SymbolSourceRangeFromTarget(line, col uint32) (src Range, ok bool) {\n\tlm, ok := sm.TargetSymbolRangeToSource[line]\n\tif !ok {\n\t\treturn\n\t}\n\tsrc, ok = lm[col]\n\treturn\n}\n\n// Add an item to the lookup.\nfunc (sm *SourceMap) Add(src Expression, tgt Range) (updatedFrom Position) {\n\tsm.Expressions = append(sm.Expressions, src.Value)\n\tsrcIndex := src.Range.From.Index\n\ttgtIndex := tgt.From.Index\n\n\tlines := strings.Split(src.Value, \"\\n\")\n\tfor lineIndex, line := range lines {\n\t\tsrcLine := src.Range.From.Line + uint32(lineIndex)\n\t\ttgtLine := tgt.From.Line + uint32(lineIndex)\n\n\t\tvar srcCol, tgtCol uint32\n\t\tif lineIndex == 0 {\n\t\t\t// First line can have an offset.\n\t\t\tsrcCol += src.Range.From.Col\n\t\t\ttgtCol += tgt.From.Col\n\t\t}\n\n\t\t// Process the cols.\n\t\tfor _, r := range line {\n\t\t\tif _, ok := sm.SourceLinesToTarget[srcLine]; !ok {\n\t\t\t\tsm.SourceLinesToTarget[srcLine] = make(map[uint32]Position)\n\t\t\t}\n\t\t\tsm.SourceLinesToTarget[srcLine][srcCol] = NewPosition(tgtIndex, tgtLine, tgtCol)\n\n\t\t\tif _, ok := sm.TargetLinesToSource[tgtLine]; !ok {\n\t\t\t\tsm.TargetLinesToSource[tgtLine] = make(map[uint32]Position)\n\t\t\t}\n\t\t\tsm.TargetLinesToSource[tgtLine][tgtCol] = NewPosition(srcIndex, srcLine, srcCol)\n\n\t\t\t// Ignore invalid runes.\n\t\t\trlen := utf8.RuneLen(r)\n\t\t\tif rlen < 0 {\n\t\t\t\trlen = 1\n\t\t\t}\n\t\t\tsrcCol += uint32(rlen)\n\t\t\ttgtCol += uint32(rlen)\n\t\t\tsrcIndex += int64(rlen)\n\t\t\ttgtIndex += int64(rlen)\n\t\t}\n\n\t\t// LSPs include the newline char as a col.\n\t\tif _, ok := sm.SourceLinesToTarget[srcLine]; !ok {\n\t\t\tsm.SourceLinesToTarget[srcLine] = make(map[uint32]Position)\n\t\t}\n\t\tsm.SourceLinesToTarget[srcLine][srcCol] = NewPosition(tgtIndex, tgtLine, tgtCol)\n\n\t\tif _, ok := sm.TargetLinesToSource[tgtLine]; !ok {\n\t\t\tsm.TargetLinesToSource[tgtLine] = make(map[uint32]Position)\n\t\t}\n\t\tsm.TargetLinesToSource[tgtLine][tgtCol] = NewPosition(srcIndex, srcLine, srcCol)\n\n\t\tsrcIndex++\n\t\ttgtIndex++\n\t}\n\treturn src.Range.From\n}\n\n// TargetPositionFromSource looks up the target position using the source position.\nfunc (sm *SourceMap) TargetPositionFromSource(line, col uint32) (tgt Position, ok bool) {\n\tlm, ok := sm.SourceLinesToTarget[line]\n\tif !ok {\n\t\treturn\n\t}\n\ttgt, ok = lm[col]\n\treturn\n}\n\n// SourcePositionFromTarget looks the source position using the target position.\n// If a source exists on the line but not the col, the function will search backwards.\nfunc (sm *SourceMap) SourcePositionFromTarget(line, col uint32) (src Position, ok bool) {\n\tlm, ok := sm.TargetLinesToSource[line]\n\tif !ok {\n\t\treturn\n\t}\n\tfor {\n\t\tsrc, ok = lm[col]\n\t\tif ok || col == 0 {\n\t\t\treturn\n\t\t}\n\t\tcol--\n\t}\n}\n"
  },
  {
    "path": "parser/v2/sourcemap_test.go",
    "content": "package parser\n\nimport (\n\t\"sort\"\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\n// Test data.\n//\n//\t|  - | 0 1 2 3 4 5 6 7 8 9\n//\t|  - | - - - - - - - - -\n//\t|  0 |\n//\t|  1 |   a b c d e f g h i\n//\t|  2 |   j k l m n o\n//\t|  3 |   p q r s t u v\n//\t|  4 |\n//\t|  5 |   w x y\n//\t|  6 |   z\n//\t|  7 |   m u l t i\n//\t|  8 | l i n e\n//\t|  9 | m a t c h\n//\t| 10 | 生 日 快 乐\nfunc pos(index, line, col int) parse.Position {\n\treturn parse.Position{\n\t\tIndex: index,\n\t\tLine:  line,\n\t\tCol:   col,\n\t}\n}\n\nfunc TestSourceMapPosition(t *testing.T) {\n\tsm := NewSourceMap()\n\n\t// Test that out of bounds requests don't return results.\n\tt.Run(\"out of bounds\", func(t *testing.T) {\n\t\tactualTarget, ok := sm.TargetPositionFromSource(20, 10)\n\t\tif ok {\n\t\t\tt.Errorf(\"searching for a source position that's not in the map should not result in a target position, but got %v\", actualTarget)\n\t\t}\n\t\tactualSource, ok := sm.SourcePositionFromTarget(20, 10)\n\t\tif ok {\n\t\t\tt.Errorf(\"searching for a target position that's not in the map should not result in a source position, but got %v\", actualSource)\n\t\t}\n\t})\n\n\tvar tests = []struct {\n\t\tname       string\n\t\tsetup      func(sm *SourceMap)\n\t\tsource     Position\n\t\ttarget     Position\n\t\texpectedOK bool\n\t}{\n\t\t{\n\t\t\tname: \"searching within the map returns a result\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\tsm.Add(NewExpression(\"abc\", pos(0, 1, 1), pos(2, 1, 3)),\n\t\t\t\t\tRange{From: NewPosition(0, 5, 1), To: NewPosition(0, 5, 3)})\n\t\t\t},\n\t\t\tsource: NewPosition(0, 1, 1), // a\n\t\t\ttarget: NewPosition(0, 5, 1),\n\t\t},\n\t\t{\n\t\t\tname: \"offsets within the match are handled\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\tsm.Add(NewExpression(\"abc\", pos(0, 1, 1), pos(2, 1, 3)),\n\t\t\t\t\tRange{From: NewPosition(0, 5, 1), To: NewPosition(0, 5, 3)})\n\t\t\t},\n\t\t\tsource: NewPosition(1, 1, 2), // b\n\t\t\ttarget: NewPosition(1, 5, 2),\n\t\t},\n\t\t{\n\t\t\tname: \"the match that starts closest to the source is returned\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\tsm.Add(NewExpression(\"rst\", pos(4, 3, 3), pos(7, 3, 6)),\n\t\t\t\t\tRange{From: NewPosition(0, 8, 6), To: NewPosition(0, 8, 9)})\n\t\t\t\t// s is inside rst.\n\t\t\t\tsm.Add(NewExpression(\"s\", pos(-1, 3, 4), pos(-1, 3, 4)),\n\t\t\t\t\tRange{From: NewPosition(-1, 8, 7), To: NewPosition(-1, 8, 7)})\n\t\t\t},\n\t\t\tsource: NewPosition(-1, 3, 4), // s\n\t\t\ttarget: NewPosition(-1, 8, 7),\n\t\t},\n\t\t{\n\t\t\tname: \"the start line within a multiline match is detected\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\t// Multi-line match.\n\t\t\t\tsm.Add(NewExpression(\"multi\\nline\\nmatch\", pos(0, 0, 0), pos(16, 2, 5)),\n\t\t\t\t\tRange{From: NewPosition(1, 1, 1), To: NewPosition(17, 3, 5)})\n\t\t\t},\n\t\t\tsource: NewPosition(0, 0, 0), // m (ulti)\n\t\t\ttarget: NewPosition(1, 1, 1),\n\t\t},\n\t\t{\n\t\t\tname: \"the middle line within a multiline match is detected\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\t// Multi-line match.\n\t\t\t\tsm.Add(NewExpression(\"multi\\nline\\nmatch\", pos(0, 0, 0), pos(16, 2, 5)),\n\t\t\t\t\tRange{From: NewPosition(1, 1, 1), To: NewPosition(17, 3, 5)})\n\t\t\t},\n\t\t\tsource: NewPosition(7, 1, 1), // (l) i (ne)\n\t\t\ttarget: NewPosition(8, 2, 1),\n\t\t},\n\t\t{\n\t\t\tname: \"the final line within a multiline match is detected\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\t// Multi-line match.\n\t\t\t\tsm.Add(NewExpression(\"multi\\nline\\nmatch\", pos(0, 0, 0), pos(16, 2, 5)),\n\t\t\t\t\tRange{From: NewPosition(1, 1, 1), To: NewPosition(17, 3, 5)})\n\t\t\t},\n\t\t\tsource: NewPosition(11, 2, 0), // m (atch)\n\t\t\ttarget: NewPosition(12, 3, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"unicode characters are indexed correctly (sheng)\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\tsm.Add(NewExpression(\"生日快乐\", pos(0, 10, 0), pos(12, 10, 4)),\n\t\t\t\t\tRange{From: NewPosition(1, 11, 1), To: NewPosition(13, 11, 5)})\n\t\t\t},\n\t\t\tsource: NewPosition(0, 10, 0), // 生\n\t\t\ttarget: NewPosition(1, 11, 1),\n\t\t},\n\t\t{\n\t\t\tname: \"unicode characters are indexed correctly (ri)\",\n\t\t\tsetup: func(sm *SourceMap) {\n\t\t\t\tsm.Add(NewExpression(\"生日快乐\", pos(0, 10, 0), pos(12, 10, 4)),\n\t\t\t\t\tRange{From: NewPosition(1, 11, 1), To: NewPosition(13, 11, 5)})\n\t\t\t},\n\t\t\tsource: NewPosition(3, 10, 3), // 日\n\t\t\ttarget: NewPosition(4, 11, 4),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tsm := NewSourceMap()\n\t\t\ttt.setup(sm)\n\t\t\tactualTarget, ok := sm.TargetPositionFromSource(uint32(tt.source.Line), uint32(tt.source.Col))\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"TargetPositionFromSource: expected result from source %v, got no results\", tt.source)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.target, actualTarget); diff != \"\" {\n\t\t\t\tlines := keys(sm.SourceLinesToTarget)\n\t\t\t\tsort.Slice(lines, func(i, j int) bool {\n\t\t\t\t\treturn lines[i] < lines[j]\n\t\t\t\t})\n\t\t\t\tfor _, lineIndex := range lines {\n\t\t\t\t\tcols := keys(sm.SourceLinesToTarget[lineIndex])\n\t\t\t\t\tsort.Slice(cols, func(i, j int) bool {\n\t\t\t\t\t\treturn cols[i] < cols[j]\n\t\t\t\t\t})\n\t\t\t\t\tt.Error(lineIndex, cols)\n\t\t\t\t}\n\t\t\t\tt.Error(\"TargetPositionFromSource\\n\\n\" + diff)\n\t\t\t}\n\t\t\tactualSource, ok := sm.SourcePositionFromTarget(actualTarget.Line, actualTarget.Col)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"SourcePositionFromTarget: expected result, got no results\")\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.source, actualSource); diff != \"\" {\n\t\t\t\tt.Error(\"SourcePositionFromTarget\\n\\n\" + diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc keys[K comparable, V any](m map[K]V) (keys []K) {\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "parser/v2/stringexpressionparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n)\n\nvar stringExpression = parse.Func(func(pi *parse.Input) (n Node, matched bool, err error) {\n\t// Check the prefix first.\n\tif _, matched, err = parse.Or(parse.String(\"{ \"), parse.String(\"{\")).Parse(pi); err != nil || !matched {\n\t\treturn\n\t}\n\n\t// Once we have a prefix, we must have an expression that returns a string, with optional err.\n\tr := &StringExpression{}\n\tif r.Expression, err = parseGoSliceArgs(pi); err != nil {\n\t\t// We return true because we should have completed the string expression, but didn't.\n\t\t// That means we found a node, but the node is invalid (has an error).\n\t\treturn r, true, err\n\t}\n\n\t// Clear any optional whitespace.\n\t_, _, _ = parse.OptionalWhitespace.Parse(pi)\n\n\t// }\n\tif _, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !matched {\n\t\treturn r, true, parse.Error(\"string expression: missing close brace\", pi.Position())\n\t}\n\n\t// Parse trailing whitespace.\n\tws, _, err := parse.Whitespace.Parse(pi)\n\tif err != nil {\n\t\treturn r, true, err\n\t}\n\tr.TrailingSpace, err = NewTrailingSpace(ws)\n\tif err != nil {\n\t\treturn r, true, err\n\t}\n\n\treturn r, true, nil\n})\n"
  },
  {
    "path": "parser/v2/stringexpressionparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestStringExpressionParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *StringExpression\n\t}{\n\t\t{\n\t\t\tname:  \"basic expression\",\n\t\t\tinput: `{ \"this\" }`,\n\t\t\texpected: &StringExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `\"this\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 2,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\n\t\t\t\t\t\t\tIndex: 8,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"no spaces\",\n\t\t\tinput: `{\"this\"}`,\n\t\t\texpected: &StringExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `\"this\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiple lines\",\n\t\t\tinput: `{ test{}.Call(a,\n\t\tb,\n\t  c) }`,\n\t\t\texpected: &StringExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"test{}.Call(a,\\n\\t\\tb,\\n\\t  c)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 2,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\n\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tan, matched, err := stringExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tactual := an.(*StringExpression)\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\n\t\t\t// Check the index.\n\t\t\tcut := tt.input[actual.Expression.Range.From.Index:actual.Expression.Range.To.Index]\n\t\t\tif tt.expected.Expression.Value != cut {\n\t\t\t\tt.Errorf(\"range, expected %q, got %q\", tt.expected.Expression.Value, cut)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/structure.go",
    "content": "package parser\n\n// TemplateFileNodes are the top level nodes of a templ file.\nvar (\n\t// css name() { ... }\n\t_ TemplateFileNode = (*CSSTemplate)(nil)\n\t// templ name() { ... }\n\t_ TemplateFileNode = (*HTMLTemplate)(nil)\n\t// script name() { ... }\n\t_ TemplateFileNode = (*ScriptTemplate)(nil)\n\t// Go code within a templ file.\n\t_ TemplateFileNode = (*TemplateFileGoExpression)(nil)\n)\n\n// Nodes are all the nodes you can find in a `templ` component.\nvar (\n\t_ Node = (*Text)(nil)\n\t_ Node = (*Element)(nil)\n\t_ Node = (*ScriptElement)(nil)\n\t_ Node = (*RawElement)(nil)\n\t_ Node = (*GoComment)(nil)\n\t_ Node = (*HTMLComment)(nil)\n\t_ Node = (*CallTemplateExpression)(nil)\n\t_ Node = (*TemplElementExpression)(nil)\n\t_ Node = (*ChildrenExpression)(nil)\n\t_ Node = (*IfExpression)(nil)\n\t_ Node = (*SwitchExpression)(nil)\n\t_ Node = (*ForExpression)(nil)\n\t_ Node = (*StringExpression)(nil)\n\t_ Node = (*GoCode)(nil)\n\t_ Node = (*Whitespace)(nil)\n\t_ Node = (*DocType)(nil)\n)\n\n// Element nodes can have the following attributes.\nvar (\n\t_ Attribute = (*BoolConstantAttribute)(nil)\n\t_ Attribute = (*ConstantAttribute)(nil)\n\t_ Attribute = (*BoolExpressionAttribute)(nil)\n\t_ Attribute = (*ExpressionAttribute)(nil)\n\t_ Attribute = (*SpreadAttributes)(nil)\n\t_ Attribute = (*ConditionalAttribute)(nil)\n)\n"
  },
  {
    "path": "parser/v2/switchexpressionparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\nvar switchExpression parse.Parser[Node] = switchExpressionParser{}\n\ntype switchExpressionParser struct{}\n\nfunc (switchExpressionParser) Parse(pi *parse.Input) (n Node, matched bool, err error) {\n\tstart := pi.Index()\n\n\t// Check the prefix first.\n\tif !peekPrefix(pi, \"switch \") {\n\t\tpi.Seek(start)\n\t\treturn n, false, nil\n\t}\n\n\t// Parse the Go switch expression.\n\tr := &SwitchExpression{}\n\tif r.Expression, err = parseGo(\"switch\", pi, goexpression.Switch); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Eat \" {\\n\".\n\tif _, matched, err = parse.All(openBraceWithOptionalPadding, parse.NewLine).Parse(pi); err != nil || !matched {\n\t\terr = parse.Error(\"switch: \"+unterminatedMissingCurly, pi.PositionAt(start))\n\t\treturn r, true, err\n\t}\n\n\t// Once we've had the start of a switch block, we must conclude the block.\n\n\t// Read the optional 'case' nodes.\n\tfor {\n\t\tvar ce CaseExpression\n\t\tce, matched, err = caseExpressionParser.Parse(pi)\n\t\tif err != nil {\n\t\t\t// Capture the case for the LSP.\n\t\t\tr.Cases = append(r.Cases, ce)\n\t\t\treturn r, true, err\n\t\t}\n\t\tif !matched {\n\t\t\tbreak\n\t\t}\n\t\tr.Cases = append(r.Cases, ce)\n\t}\n\n\tif err = assertLastCaseDoesNotContainFallthrough(r.Cases); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Optional whitespace.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\treturn r, false, err\n\t}\n\n\t// Read the required closing brace.\n\tif _, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !matched {\n\t\terr = parse.Error(\"switch: \"+unterminatedMissingEnd, pi.Position())\n\t\treturn r, true, err\n\t}\n\n\tr.Range = NewRange(pi.PositionAt(start), pi.Position())\n\treturn r, true, nil\n}\n\nconst fallthroughInLastCaseError = \"switch: fallthrough cannot be used in the last case of a switch statement\"\n\nfunc assertLastCaseDoesNotContainFallthrough(cases []CaseExpression) error {\n\tif len(cases) == 0 {\n\t\treturn nil\n\t}\n\tlastCase := cases[len(cases)-1]\n\tif len(lastCase.Children) == 0 {\n\t\treturn nil\n\t}\n\tlastChild := lastCase.Children[len(lastCase.Children)-1]\n\tff, isFallthrough := lastChild.(*Fallthrough)\n\tif !isFallthrough {\n\t\treturn nil\n\t}\n\tpos := parse.Position{\n\t\tIndex: int(ff.Range.From.Index),\n\t\tLine:  int(ff.Range.From.Line),\n\t\tCol:   int(ff.Range.From.Col),\n\t}\n\treturn parse.Error(fallthroughInLastCaseError, pos)\n}\n\nvar caseExpressionStartParser = parse.Func(func(pi *parse.Input) (r Expression, matched bool, err error) {\n\tstart := pi.Index()\n\n\t// Optional whitespace.\n\tif _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {\n\t\treturn r, false, err\n\t}\n\n\t// Strip leading whitespace and look for `case ` or `default`.\n\tif !peekPrefix(pi, \"case \", \"default\") {\n\t\tpi.Seek(start)\n\t\treturn r, false, nil\n\t}\n\t// Parse the Go expression.\n\tif r, err = parseGo(\"case\", pi, goexpression.Case); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Eat terminating newline.\n\t_, _, _ = parse.ZeroOrMore(parse.String(\" \")).Parse(pi)\n\t_, _, _ = parse.NewLine.Parse(pi)\n\n\treturn r, true, nil\n})\n\nvar untilNextCaseOrEnd = parse.Any(StripType(caseExpressionStartParser), StripType(closeBraceWithOptionalPadding))\n\nvar caseExpressionParser = parse.Func(func(pi *parse.Input) (r CaseExpression, matched bool, err error) {\n\tif r.Expression, matched, err = caseExpressionStartParser.Parse(pi); err != nil || !matched {\n\t\treturn r, matched, err\n\t}\n\n\t// Read until the next case statement, default, or end of the block.\n\tpr := newTemplateNodeParser(untilNextCaseOrEnd, \"closing brace or case expression\")\n\tvar nodes Nodes\n\tif nodes, matched, err = pr.Parse(pi); err != nil || !matched {\n\t\t// Populate the nodes anyway, so that the LSP can use them.\n\t\tr.Children = nodes.Nodes\n\t\tif err != nil {\n\t\t\treturn r, true, err\n\t\t}\n\t\terr = parse.Error(\"case: expected nodes, but none were found\", pi.Position())\n\t\treturn r, true, err\n\t}\n\tr.Children = nodes.Nodes\n\n\t// If we have children, validate that no statement in the middle is a fallthrough.\n\tif err = assertFallthroughMustBeLastInCase(r.Children); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Optional whitespace.\n\tif _, matched, err = parse.OptionalWhitespace.Parse(pi); err != nil || !matched {\n\t\treturn r, true, err\n\t}\n\n\treturn r, true, nil\n})\n\nconst fallthroughMustBeLastInCaseError = \"case: fallthrough can only be used as the last statement in a case block\"\n\nfunc assertFallthroughMustBeLastInCase(nodes []Node) error {\n\tif len(nodes) == 0 {\n\t\treturn nil\n\t}\n\tfor i, n := range nodes {\n\t\tif i == len(nodes)-1 {\n\t\t\tbreak\n\t\t}\n\t\tif ff, isFallthrough := n.(*Fallthrough); isFallthrough {\n\t\t\tpos := parse.Position{\n\t\t\t\tIndex: int(ff.Range.From.Index),\n\t\t\t\tLine:  int(ff.Range.From.Line),\n\t\t\t\tCol:   int(ff.Range.From.Col),\n\t\t\t}\n\t\t\treturn parse.Error(fallthroughMustBeLastInCaseError, pos)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "parser/v2/switchexpressionparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestSwitchExpressionParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *SwitchExpression\n\t}{\n\t\t{\n\t\t\tname: \"switch: simple\",\n\t\t\tinput: `switch \"stringy\" {\n}`,\n\t\t\texpected: &SwitchExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `\"stringy\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 20, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"switch: default only\",\n\t\t\tinput: `switch \"stringy\" {\ndefault:\n\t<span>\n\t  { \"span content\" }\n\t</span>\n}`,\n\t\t\texpected: &SwitchExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `\"stringy\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCases: []CaseExpression{\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"default:\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 19,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 28,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 29,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t\t\t&Element{\n\t\t\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 30, Line: 2, Col: 2},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 34, Line: 2, Col: 6},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 39,\n\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tValue: \"\\n\\t  \"},\n\t\t\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 41,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 55,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   19,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 29, Line: 2, Col: 1},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 67, Line: 5, Col: 0},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 68, Line: 5, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"switch: one case\",\n\t\t\tinput: `switch \"stringy\" {\n\tcase \"stringy\":\n<span>\n  { \"span content\" }\n</span>\n}`,\n\t\t\texpected: &SwitchExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `\"stringy\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCases: []CaseExpression{\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"case \\\"stringy\\\":\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 20,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Element{\n\t\t\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 37, Line: 2, Col: 1},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 41, Line: 2, Col: 5},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 42,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 45,\n\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tValue: \"\\n  \"},\n\t\t\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 47,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 61,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   18,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 36, Line: 2, Col: 0},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 72, Line: 5, Col: 0},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 73, Line: 5, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"switch: two cases\",\n\t\t\tinput: `switch \"stringy\" {\n\tcase \"a\":\n\t\t{ \"A\" }\n\tcase \"b\":\n\t\t{ \"B\" }\n}`,\n\t\t\texpected: &SwitchExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `\"stringy\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCases: []CaseExpression{\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"case \\\"a\\\":\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 20,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 29,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\\t\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"A\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 34,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 37,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"case \\\"b\\\":\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 41,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 50,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 51,\n\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 53,\n\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\\t\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 55,\n\t\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 58,\n\t\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 62, Line: 5, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"switch: two cases with one fallthrough case\",\n\t\t\tinput: `switch \"stringy\" {\n\tcase \"a\":\n\t\tfallthrough\n\tcase \"b\":\n\t\t{ \"B\" }\n}`,\n\t\t\texpected: &SwitchExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `\"stringy\"`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 7,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCases: []CaseExpression{\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"case \\\"a\\\":\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 20,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 29,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\\t\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&Fallthrough{\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 44,\n\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"case \\\"b\\\":\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 45,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 54,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 55,\n\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 57,\n\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\\t\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"B\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 59,\n\t\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 62,\n\t\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\t\tCol:   7,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 66, Line: 5, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, matched, err := switchExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIncompleteSwitch(t *testing.T) {\n\tt.Run(\"no opening brace\", func(t *testing.T) {\n\t\tinput := parse.NewInput(`switch with no brace`)\n\t\t_, matched, err := switchExpression.Parse(input)\n\t\tif err == nil {\n\t\t\tt.Fatal(\"expected an error, got nil\")\n\t\t}\n\t\tif !matched {\n\t\t\tt.Fatal(\"expected a match, because we started with the text 'switch'\")\n\t\t}\n\t\tpe, isParseError := err.(parse.ParseError)\n\t\tif !isParseError {\n\t\t\tt.Fatalf(\"expected a parse error, got %T\", err)\n\t\t}\n\t\tif pe.Msg != \"switch: \"+unterminatedMissingCurly {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif pe.Pos.Line != 0 {\n\t\t\tt.Errorf(\"unexpected line: %d\", pe.Pos.Line)\n\t\t}\n\t})\n\tt.Run(\"capitalised Switch\", func(t *testing.T) {\n\t\tinput := parse.NewInput(`Switch with no brace`)\n\t\t_, matched, err := switchExpression.Parse(input)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif matched {\n\t\t\tt.Fatal(\"expected a non match\")\n\t\t}\n\t})\n}\n\nfunc TestSwitchWithImproperCaseFallthrough(t *testing.T) {\n\tinput := parse.NewInput(`switch \"stringy\" {\n\tcase \"a\":\n\t\tfallthrough extra tokens\n\tcase \"b\":\n\t\t{ \"B\" }\n}`)\n\t_, matched, err := switchExpression.Parse(input)\n\tif err == nil {\n\t\tt.Fatal(\"expected an error, got nil\")\n\t}\n\tif !matched {\n\t\tt.Fatal(\"expected a match, because we started with the text 'switch'\")\n\t}\n\tpe, isParseError := err.(parse.ParseError)\n\tif !isParseError {\n\t\tt.Fatalf(\"expected a parse error, got %T\", err)\n\t}\n\tif pe.Msg != \"expected newline after fallthrough\" {\n\t\tt.Errorf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestSwitchWithNonTerminalFallthrough(t *testing.T) {\n\tinput := parse.NewInput(`switch \"stringy\" {\n\tcase \"a\":\n\t\tfallthrough\n\t\t<span></span>\n\tcase \"b\":\n\t\t{ \"B\" }\n}`)\n\t_, matched, err := switchExpression.Parse(input)\n\tif err == nil {\n\t\tt.Fatal(\"expected an error, got nil\")\n\t}\n\tif !matched {\n\t\tt.Fatal(\"expected a match, because we started with the text 'switch'\")\n\t}\n\tpe, isParseError := err.(parse.ParseError)\n\tif !isParseError {\n\t\tt.Fatalf(\"expected a parse error, got %T\", err)\n\t}\n\tif pe.Msg != fallthroughMustBeLastInCaseError {\n\t\tt.Errorf(\"unexpected error: %v\", err)\n\t}\n}\n\nfunc TestSwitchWithFallthroughInFinalCase(t *testing.T) {\n\tinput := parse.NewInput(`switch \"stringy\" {\n\tcase \"a\":\n\t\t{ \"A\" }\n\tcase \"b\":\n\t\tfallthrough\n}`)\n\t_, matched, err := switchExpression.Parse(input)\n\tif err == nil {\n\t\tt.Fatal(\"expected an error, got nil\")\n\t}\n\tif !matched {\n\t\tt.Fatal(\"expected a match, because we started with the text 'switch'\")\n\t}\n\tpe, isParseError := err.(parse.ParseError)\n\tif !isParseError {\n\t\tt.Fatalf(\"expected a parse error, got %T\", err)\n\t}\n\tif pe.Msg != fallthroughInLastCaseError {\n\t\tt.Errorf(\"unexpected error: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "parser/v2/templatefile.go",
    "content": "package parser\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/a-h/parse\"\n)\n\nfunc Parse(fileName string) (*TemplateFile, error) {\n\tfc, err := os.ReadFile(fileName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ParseString(string(fc))\n}\n\nfunc getDefaultPackageName(fileName string) (pkg string) {\n\tparent := filepath.Base(filepath.Dir(fileName))\n\tif !isGoIdentifier(parent) {\n\t\treturn \"main\"\n\t}\n\treturn parent\n}\n\nfunc isGoIdentifier(s string) bool {\n\tif len(s) == 0 {\n\t\treturn false\n\t}\n\tfor i, r := range s {\n\t\tif unicode.IsLetter(r) || r == '_' {\n\t\t\tcontinue\n\t\t}\n\t\tif i > 0 && unicode.IsDigit(r) {\n\t\t\tcontinue\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc ParseString(template string) (*TemplateFile, error) {\n\ttf, matched, err := NewTemplateFileParser(\"main\").Parse(parse.NewInput(template))\n\tif err != nil {\n\t\treturn tf, err\n\t}\n\tif !matched {\n\t\terr = ErrTemplateNotFound\n\t}\n\treturn tf, err\n}\n\n// NewTemplateFileParser creates a new TemplateFileParser.\nfunc NewTemplateFileParser(pkg string) TemplateFileParser {\n\treturn TemplateFileParser{\n\t\tDefaultPackage: pkg,\n\t}\n}\n\nvar ErrLegacyFileFormat = errors.New(\"legacy file format - run templ migrate\")\nvar ErrTemplateNotFound = errors.New(\"template not found\")\n\ntype TemplateFileParser struct {\n\tDefaultPackage string\n}\n\nvar legacyPackageParser = parse.String(\"{% package\")\n\nfunc (p TemplateFileParser) Parse(pi *parse.Input) (tf *TemplateFile, matched bool, err error) {\n\t// If we're parsing a legacy file, complain that migration needs to happen.\n\t_, matched, err = legacyPackageParser.Parse(pi)\n\tif err != nil {\n\t\treturn\n\t}\n\tif matched {\n\t\treturn tf, false, ErrLegacyFileFormat\n\t}\n\n\t// Read until the package.\n\ttf = &TemplateFile{}\n\tfor {\n\t\t// Package.\n\t\t// package name\n\t\tfrom := pi.Position()\n\t\ttf.Package, matched, err = pkg.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif matched {\n\t\t\tbreak\n\t\t}\n\n\t\tvar line string\n\t\tline, matched, err = stringUntilNewLine.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif !matched {\n\t\t\tbreak\n\t\t}\n\t\tvar newLine string\n\t\tnewLine, _, _ = parse.NewLine.Parse(pi)\n\t\ttf.Header = append(tf.Header, &TemplateFileGoExpression{Expression: NewExpression(line+newLine, from, pi.Position()), BeforePackage: true})\n\t}\n\n\t// Strip any whitespace between the template declaration and the first template.\n\t_, _, _ = parse.OptionalWhitespace.Parse(pi)\n\nouter:\n\tfor {\n\t\t// Optional templates, CSS, and script templates.\n\t\t// templ Name(p Parameter)\n\t\tvar tn *HTMLTemplate\n\t\ttn, matched, err = template.Parse(pi)\n\t\tif err != nil {\n\t\t\ttf.Nodes = append(tf.Nodes, tn)\n\t\t\treturn tf, false, err\n\t\t}\n\t\tif matched {\n\t\t\ttf.Nodes = append(tf.Nodes, tn)\n\t\t\t_, _, _ = parse.OptionalWhitespace.Parse(pi)\n\t\t\tcontinue\n\t\t}\n\n\t\t// css Name()\n\t\tvar cn *CSSTemplate\n\t\tcn, matched, err = cssParser.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn tf, false, err\n\t\t}\n\t\tif matched {\n\t\t\ttf.Nodes = append(tf.Nodes, cn)\n\t\t\t_, _, _ = parse.OptionalWhitespace.Parse(pi)\n\t\t\tcontinue\n\t\t}\n\n\t\t// script Name()\n\t\tvar sn *ScriptTemplate\n\t\tsn, matched, err = scriptTemplateParser.Parse(pi)\n\t\tif err != nil {\n\t\t\treturn tf, false, err\n\t\t}\n\t\tif matched {\n\t\t\ttf.Nodes = append(tf.Nodes, sn)\n\t\t\t_, _, _ = parse.OptionalWhitespace.Parse(pi)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Anything that isn't template content is Go code.\n\t\tcode := new(strings.Builder)\n\t\tfrom := pi.Position()\n\tinner:\n\t\tfor {\n\t\t\t// Check to see if this line isn't Go code.\n\t\t\tlast := pi.Index()\n\t\t\tvar l string\n\t\t\tif l, matched, err = stringUntilNewLineOrEOF.Parse(pi); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\thasTemplatePrefix := strings.HasPrefix(l, \"templ \") || strings.HasPrefix(l, \"css \") || strings.HasPrefix(l, \"script \")\n\t\t\tif hasTemplatePrefix && strings.Contains(l, \"(\") {\n\t\t\t\t// Unread the line.\n\t\t\t\tpi.Seek(last)\n\t\t\t\t// Take the code so far.\n\t\t\t\tif code.Len() > 0 {\n\t\t\t\t\texpr := NewExpression(strings.TrimSpace(code.String()), from, pi.Position())\n\t\t\t\t\ttf.Nodes = append(tf.Nodes, &TemplateFileGoExpression{Expression: expr})\n\t\t\t\t}\n\t\t\t\t// Carry on parsing.\n\t\t\t\tbreak inner\n\t\t\t}\n\t\t\tcode.WriteString(l)\n\n\t\t\t// Eat the newline or EOF that we read until.\n\t\t\tvar newLine string\n\t\t\tif newLine, matched, err = parse.NewLine.Parse(pi); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcode.WriteString(newLine)\n\t\t\tif _, isEOF, _ := parse.EOF[string]().Parse(pi); isEOF {\n\t\t\t\tif code.Len() > 0 {\n\t\t\t\t\texpr := NewExpression(strings.TrimSpace(code.String()), from, pi.Position())\n\t\t\t\t\ttf.Nodes = append(tf.Nodes, &TemplateFileGoExpression{Expression: expr})\n\t\t\t\t}\n\t\t\t\t// Stop parsing.\n\t\t\t\tbreak outer\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tf, true, nil\n}\n"
  },
  {
    "path": "parser/v2/templatefile_test.go",
    "content": "package parser\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestTemplateFileParser(t *testing.T) {\n\tt.Run(\"requests migration of legacy formats\", func(t *testing.T) {\n\t\tinput := `{% package templates %}\n`\n\t\t_, err := ParseString(input)\n\t\tif err == nil {\n\t\t\tt.Error(\"expected ErrLegacyFileFormat, got nil\")\n\t\t}\n\t\tif err != ErrLegacyFileFormat {\n\t\t\tt.Errorf(\"expected ErrLegacyFileFormat, got %v\", err)\n\t\t}\n\t})\n\tt.Run(\"but can accept a package expression, if one is provided\", func(t *testing.T) {\n\t\tinput := `package goof\n\ntempl Hello() {\n\tHello\n}`\n\t\ttf, err := ParseString(input)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to parse template, with t.Fatalf(parser %v\", err)\n\t\t}\n\t\tif len(tf.Nodes) != 1 {\n\t\t\tt.Errorf(\"expected 2 nodes, got %+v\", tf.Nodes)\n\t\t}\n\t\tif tf.Package.Expression.Value != \"package goof\" {\n\t\t\tt.Errorf(\"expected \\\"goof\\\", got %q\", tf.Package.Expression.Value)\n\t\t}\n\t})\n\tt.Run(\"can start with comments\", func(t *testing.T) {\n\t\tinput := `// Example comment.\npackage goof\n\ntempl Hello() {\n\tHello\n}`\n\t\ttf, err := ParseString(input)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to parse template, with t.Fatalf(parser %v\", err)\n\t\t}\n\t\tif len(tf.Nodes) != 1 {\n\t\t\tt.Errorf(\"expected 2 node, got %d nodes with content %+v\", len(tf.Nodes), tf.Nodes)\n\t\t}\n\t})\n\tt.Run(\"template files can end with Go expressions\", func(t *testing.T) {\n\t\tinput := `package goof\n\nconst x = \"123\"\n\ntempl Hello() {\n\tHello\n}\n\nconst y = \"456\"\n`\n\t\ttf, err := ParseString(input)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to parse template, with t.Fatalf(parser %v\", err)\n\t\t}\n\t\tif len(tf.Nodes) != 3 {\n\t\t\tvar nodeTypes []string\n\t\t\tfor _, n := range tf.Nodes {\n\t\t\t\tnodeTypes = append(nodeTypes, reflect.TypeOf(n).Name())\n\t\t\t}\n\t\t\tt.Fatalf(\"expected 3 nodes, got %d nodes, %v\", len(tf.Nodes), nodeTypes)\n\t\t}\n\t\texpr, isGoExpression := tf.Nodes[0].(*TemplateFileGoExpression)\n\t\tif !isGoExpression {\n\t\t\tt.Errorf(\"0: expected expression, got %t\", tf.Nodes[2])\n\t\t}\n\t\tif expr.Expression.Value != `const x = \"123\"` {\n\t\t\tt.Errorf(\"0: unexpected expression: %q\", expr.Expression.Value)\n\t\t}\n\t\texpr, isGoExpression = tf.Nodes[2].(*TemplateFileGoExpression)\n\t\tif !isGoExpression {\n\t\t\tt.Errorf(\"2: expected expression, got %t\", tf.Nodes[2])\n\t\t}\n\t\tif expr.Expression.Value != `const y = \"456\"` {\n\t\t\tt.Errorf(\"2: unexpected expression: %q\", expr.Expression.Value)\n\t\t}\n\t})\n\tt.Run(\"template files can end with string literals\", func(t *testing.T) {\n\t\tinput := `package goof\n\nconst x = \"123\"\n\ntempl Hello() {\n\tHello\n}\n\nconst y = ` + \"`456`\"\n\t\ttf, err := ParseString(input)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to parse template, with t.Fatalf(parser %v\", err)\n\t\t}\n\t\tif len(tf.Nodes) != 3 {\n\t\t\tvar nodeTypes []string\n\t\t\tfor _, n := range tf.Nodes {\n\t\t\t\tnodeTypes = append(nodeTypes, reflect.TypeOf(n).Name())\n\t\t\t}\n\t\t\tt.Fatalf(\"expected 3 nodes, got %d nodes, %v\", len(tf.Nodes), nodeTypes)\n\t\t}\n\t\texpr, isGoExpression := tf.Nodes[0].(*TemplateFileGoExpression)\n\t\tif !isGoExpression {\n\t\t\tt.Errorf(\"0: expected expression, got %t\", tf.Nodes[2])\n\t\t}\n\t\tif expr.Expression.Value != `const x = \"123\"` {\n\t\t\tt.Errorf(\"0: unexpected expression: %q\", expr.Expression.Value)\n\t\t}\n\t\texpr, isGoExpression = tf.Nodes[2].(*TemplateFileGoExpression)\n\t\tif !isGoExpression {\n\t\t\tt.Errorf(\"2: expected expression, got %t\", tf.Nodes[2])\n\t\t}\n\t\tif expr.Expression.Value != \"const y = `456`\" {\n\t\t\tt.Errorf(\"2: unexpected expression: %q\", expr.Expression.Value)\n\t\t}\n\t})\n\t// https://github.com/a-h/templ/issues/505\n\tt.Run(\"template files can contain go expressions followed by multiline templates\", func(t *testing.T) {\n\t\tinput := `package goof\n\nvar a = \"a\"\n\ntempl template(\n\ta string,\n) {\n}`\n\t\ttf, err := ParseString(input)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to parse template, with t.Fatalf(parser %v\", err)\n\t\t}\n\t\tif len(tf.Nodes) != 2 {\n\t\t\tvar nodeTypes []string\n\t\t\tfor _, n := range tf.Nodes {\n\t\t\t\tnodeTypes = append(nodeTypes, reflect.TypeOf(n).Name())\n\t\t\t}\n\t\t\tt.Fatalf(\"expected 2 nodes, got %d nodes, %v\\n%#v\", len(tf.Nodes), nodeTypes, tf)\n\t\t}\n\t\texpr, isGoExpression := tf.Nodes[0].(*TemplateFileGoExpression)\n\t\tif !isGoExpression {\n\t\t\tt.Errorf(\"0: expected expression, got %t\", tf.Nodes[2])\n\t\t}\n\t\tif expr.Expression.Value != `var a = \"a\"` {\n\t\t\tt.Errorf(\"0: unexpected expression: %q\", expr.Expression.Value)\n\t\t}\n\t\t_, isGoExpression = tf.Nodes[1].(*HTMLTemplate)\n\t\tif !isGoExpression {\n\t\t\tt.Errorf(\"2: expected expression, got %t\", tf.Nodes[2])\n\t\t}\n\t})\n\tt.Run(\"as you type a templ file, it parses as much as it can, even if there's an error, so that the LSP functions\", func(t *testing.T) {\n\t\tinput := `package main\n\ntempl Hello(name string) {\n  if nam`\n\t\ttf, err := ParseString(input)\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"expected error, because the file is not valid, got nil\")\n\t\t}\n\t\tif len(tf.Nodes) != 1 {\n\t\t\tt.Fatalf(\"expected 1 node, got %d nodes\", len(tf.Nodes))\n\t\t}\n\t\thello, ok := tf.Nodes[0].(*HTMLTemplate)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"expected HTML template, but was %T\", tf.Nodes[0])\n\t\t}\n\t\t// Expect the range of the HTML template to be from `templ Hello` to the end of the input.\n\t\texpectedRange := Range{\n\t\t\tFrom: Position{Index: int64(len(\"package main\\n\\n\")), Line: 2, Col: 0},\n\t\t\tTo:   Position{Index: int64(len(input)), Line: 3, Col: 8},\n\t\t}\n\t\tif diff := cmp.Diff(expectedRange, hello.Range); diff != \"\" {\n\t\t\tt.Errorf(\"expected range %v, got %v\\n%s\", expectedRange, hello.Range, diff)\n\t\t}\n\t\t// Inside Hello, we expect an if expression.\n\t\tif len(hello.Children) == 0 {\n\t\t\tt.Fatalf(\"expected to find children, but didn't\")\n\t\t}\n\t\tif len(hello.Children) != 2 {\n\t\t\tt.Fatalf(\"expected 2 children (whitespace, if), got %d\", len(hello.Children))\n\t\t}\n\t\tie, ok := hello.Children[1].(*IfExpression)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"expected if expression, but was %T\", hello.Children[0])\n\t\t}\n\t\tif ie.Expression.Value != \"nam\" {\n\t\t\tt.Errorf(\"expected Go expression %q, got %q\", \"nam\", ie.Expression.Value)\n\t\t}\n\t\texpectedIfExpressionRange := Range{\n\t\t\tFrom: Position{Index: 46, Line: 3, Col: 5},\n\t\t\tTo:   Position{Index: 49, Line: 3, Col: 8},\n\t\t}\n\t\tif diff := cmp.Diff(expectedIfExpressionRange, ie.Expression.Range); diff != \"\" {\n\t\t\tt.Errorf(\"expected range %v, got %v\\n%s\", expectedIfExpressionRange, ie.Expression.Range, diff)\n\t\t}\n\t})\n}\n\nfunc TestDefaultPackageName(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"standard filename\",\n\t\t\tinput:    \"/files/on/disk/header.templ\",\n\t\t\texpected: \"disk\",\n\t\t},\n\t\t{\n\t\t\tname:     \"path that starts with numbers\",\n\t\t\tinput:    \"/files/on/123disk/header.templ\",\n\t\t\texpected: \"main\",\n\t\t},\n\t\t{\n\t\t\tname:     \"path that includes hyphens\",\n\t\t\tinput:    \"/files/on/disk-drive/header.templ\",\n\t\t\texpected: \"main\",\n\t\t},\n\t\t{\n\t\t\tname:     \"relative path\",\n\t\t\tinput:    \"header.templ\",\n\t\t\texpected: \"main\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tactual := getDefaultPackageName(tt.input)\n\t\t\tif actual != tt.expected {\n\t\t\t\tt.Errorf(\"expected %q got %q\", tt.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/templateparser.go",
    "content": "package parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/a-h/parse\"\n)\n\n// TemplateExpression.\n\n// TemplateExpression.\n// templ Func(p Parameter) {\n// templ (data Data) Func(p Parameter) {\n// templ (data []string) Func(p Parameter) {\ntype templateExpression struct {\n\tExpression Expression\n}\n\nvar templateExpressionParser = parse.Func(func(pi *parse.Input) (r templateExpression, matched bool, err error) {\n\tstart := pi.Index()\n\n\tif !peekPrefix(pi, \"templ \") {\n\t\treturn r, false, nil\n\t}\n\n\t// Once we have the prefix, everything to the brace is Go.\n\t// e.g.\n\t// templ (x []string) Test() {\n\t// becomes:\n\t// func (x []string) Test() templ.Component {\n\tif _, r.Expression, err = parseTemplFuncDecl(pi); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Eat \" {\\n\".\n\tif _, matched, err = parse.All(openBraceWithOptionalPadding, parse.StringFrom(parse.Optional(parse.NewLine))).Parse(pi); err != nil || !matched {\n\t\treturn r, true, parse.Error(\"templ: malformed templ expression, expected `templ functionName() {`\", pi.PositionAt(start))\n\t}\n\n\treturn r, true, nil\n})\n\nconst (\n\tunterminatedMissingCurly = `unterminated (missing closing '{\\n') - to escape \"for\", \"if\", \"switch\" etc. with braces, e.g. '{ \"for\" }' - https://templ.guide/syntax-and-usage/statements#ifswitchfor-within-text`\n\tunterminatedMissingEnd   = `missing end (expected '}') - https://templ.guide/syntax-and-usage/statements#ifswitchfor-within-text`\n)\n\n// Template node (element, call, if, switch, for, whitespace etc.)\nfunc newTemplateNodeParser[TUntil any](until parse.Parser[TUntil], untilName string) templateNodeParser[TUntil] {\n\treturn templateNodeParser[TUntil]{\n\t\tuntil:     until,\n\t\tuntilName: untilName,\n\t}\n}\n\ntype templateNodeParser[TUntil any] struct {\n\tuntil     parse.Parser[TUntil]\n\tuntilName string\n}\n\nvar rawElements = parse.Any(styleElement, scriptElement)\n\nvar templateNodeSkipParsers = []parse.Parser[Node]{\n\tvoidElementCloser, // </br>, </img> etc. - should be ignored.\n}\n\nvar templateNodeParsers = []parse.Parser[Node]{\n\tdocType,                // <!DOCTYPE html>\n\thtmlComment,            // <!--\n\tgoComment,              // // or /*\n\trawElements,            // <text>, <>, or <style> element (special behaviour - contents are not parsed).\n\telement,                // <a>, <br/> etc.\n\tifExpression,           // if {}\n\tforExpression,          // for {}\n\tswitchExpression,       // switch {}\n\tcallTemplateExpression, // {! TemplateName(a, b, c) }\n\ttemplElementExpression, // @TemplateName(a, b, c) { <div>Children</div> }\n\tchildrenExpression,     // { children... }\n\tgoCode,                 // {{ myval := x.myval }}\n\tstringExpression,       // { \"abc\" }\n\twhitespaceExpression,   // { \" \" }\n\tfallthroughExpression,  // fallthrough keyword in switch case statement\n\ttextParser,             // anything &amp; everything accepted...\n}\n\nfunc (p templateNodeParser[T]) Parse(pi *parse.Input) (op Nodes, matched bool, err error) {\nouter:\n\tfor {\n\t\t// Check if we've reached the end.\n\t\tif p.until != nil {\n\t\t\tstart := pi.Index()\n\t\t\t_, didMatchUntilParser, err := p.until.Parse(pi)\n\t\t\tif err != nil {\n\t\t\t\treturn op, false, err\n\t\t\t}\n\t\t\tif didMatchUntilParser {\n\t\t\t\tpi.Seek(start)\n\t\t\t\treturn op, true, nil\n\t\t\t}\n\t\t}\n\n\t\t// Skip any nodes that we don't care about.\n\t\tfor _, p := range templateNodeSkipParsers {\n\t\t\t_, didMatchSkipParser, err := p.Parse(pi)\n\t\t\tif err != nil {\n\t\t\t\treturn op, false, err\n\t\t\t}\n\t\t\tif didMatchSkipParser {\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\n\t\t// Attempt to parse a node.\n\t\t// Loop through the parsers and try to parse a node.\n\t\tvar didMatchTemplateNode bool\n\t\tfor _, p := range templateNodeParsers {\n\t\t\tvar node Node\n\t\t\tnode, didMatchTemplateNode, err = p.Parse(pi)\n\t\t\tif err != nil {\n\t\t\t\t// Even if there's an error, we might have a node that the LSP can use,\n\t\t\t\t// so return it.\n\t\t\t\tif node != nil {\n\t\t\t\t\top.Nodes = append(op.Nodes, node)\n\t\t\t\t}\n\t\t\t\treturn op, true, err\n\t\t\t}\n\t\t\tif didMatchTemplateNode {\n\t\t\t\top.Nodes = append(op.Nodes, node)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif didMatchTemplateNode {\n\t\t\tcontinue\n\t\t}\n\n\t\tif p.until == nil {\n\t\t\t// In this case, we're just reading as many nodes as we can until we can't read any more.\n\t\t\t// If we've reached here, we couldn't find a node.\n\t\t\t// The element parser checks the final node returned to make sure it's the expected close tag.\n\t\t\tbreak\n\t\t}\n\n\t\terr = UntilNotFoundError{\n\t\t\tParseError: parse.Error(fmt.Sprintf(\"%v not found\", p.untilName), pi.Position()),\n\t\t}\n\t\treturn op, true, err\n\t}\n\n\treturn op, true, nil\n}\n\ntype UntilNotFoundError struct {\n\tparse.ParseError\n}\n"
  },
  {
    "path": "parser/v2/templateparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestTemplateParser(t *testing.T) {\n\ttests := []struct {\n\t\tname        string\n\t\tinput       string\n\t\texpected    *HTMLTemplate\n\t\texpectError bool\n\t}{\n\t\t{\n\t\t\tname: \"template: no parameters\",\n\t\t\tinput: `templ Name() {\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 16, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: with receiver\",\n\t\t\tinput: `templ (data Data) Name() {\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 28, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"(data Data) Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 24,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   24,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: no spaces\",\n\t\t\tinput: `templ Name(){\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 15, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: single parameter\",\n\t\t\tinput: `templ Name(p Parameter) {\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 27, Line: 1, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(p Parameter)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: can have multiline params\",\n\t\t\tinput: `templ Multiline(\n\tparams expense,\n) {\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 39, Line: 3, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Multiline(\\n\\tparams expense,\\n)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: containing element\",\n\t\t\tinput: `templ Name(p Parameter) {\n<span>{ \"span content\" }</span>\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 59, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(p Parameter)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 27, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 31, Line: 1, Col: 5},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 34,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 48,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   22,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 26, Line: 1, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 58, Line: 2, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"template: containing element - no spacing\",\n\t\t\tinput: `templ Name(p Parameter) { <span>{ \"span content\" }</span> }`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 59, Line: 0, Col: 59},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(p Parameter)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 27, Line: 0, Col: 27},\n\t\t\t\t\t\t\tTo:   Position{Index: 31, Line: 0, Col: 31},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 34,\n\t\t\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\t\t\tCol:   34,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 48,\n\t\t\t\t\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\t\t\t\t\tCol:   48,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceHorizontal,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 26, Line: 0, Col: 26},\n\t\t\t\t\t\t\tTo:   Position{Index: 58, Line: 0, Col: 58},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: containing nested elements\",\n\t\t\tinput: `templ Name(p Parameter) {\n<div>\n  { \"div content\" }\n  <span>\n\t{ \"span content\" }\n  </span>\n</div>\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 99, Line: 7, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(p Parameter)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"div\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 27, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 30, Line: 1, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 31,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 34,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\n  \"},\n\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `\"div content\"`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 36,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 49,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   17,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&Element{\n\t\t\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 55, Line: 3, Col: 3},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 59, Line: 3, Col: 7},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 60,\n\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 62,\n\t\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tValue: \"\\n\\t\"},\n\t\t\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 64,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 78,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   17,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 54, Line: 3, Col: 2},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 91, Line: 6, Col: 0},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 26, Line: 1, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 98, Line: 7, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: containing if element\",\n\t\t\tinput: `templ Name(p Parameter) {\n\tif p.Test {\n\t\t<span>\n\t\t\t{ \"span content\" }\n\t\t</span>\n\t}\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 84, Line: 6, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(p Parameter)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 26,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&IfExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: `p.Test`,\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 36,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tThen: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 39,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 41,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\t\\t\"},\n\t\t\t\t\t\t\t&Element{\n\t\t\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 42, Line: 2, Col: 3},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 46, Line: 2, Col: 7},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 47,\n\t\t\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\t\t\tCol:   8,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 51,\n\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tValue: \"\\n\\t\\t\\t\"},\n\t\t\t\t\t\t\t\t\t&StringExpression{\n\t\t\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\t\t\tValue: `\"span content\"`,\n\t\t\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 53,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   5,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\t\t\tIndex: 67,\n\t\t\t\t\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\t\t\t\t\tCol:   19,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 41, Line: 2, Col: 2},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 81, Line: 5, Col: 1},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 27, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 82, Line: 5, Col: 2},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 82,\n\t\t\t\t\t\t\tLine:  5,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 83,\n\t\t\t\t\t\t\tLine:  6,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: inputs\",\n\t\t\tinput: `templ Name(p Parameter) {\n\t<input type=\"text\" value=\"a\" />\n\t<input type=\"text\" value=\"b\" />\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 93, Line: 3, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(p Parameter)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   23,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 26,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"input\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 28, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 33, Line: 1, Col: 7},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"text\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"type\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 34, Line: 1, Col: 8},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 38, Line: 1, Col: 12},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 34, Line: 1, Col: 8},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 45, Line: 1, Col: 19},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"a\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"value\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 46, Line: 1, Col: 20},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 51, Line: 1, Col: 25},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 46, Line: 1, Col: 20},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 55, Line: 1, Col: 29},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 27, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 60, Line: 2, Col: 1},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"input\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 61, Line: 2, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 66, Line: 2, Col: 7},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"text\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"type\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 67, Line: 2, Col: 8},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 71, Line: 2, Col: 12},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 67, Line: 2, Col: 8},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 78, Line: 2, Col: 19},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"b\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"value\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 79, Line: 2, Col: 20},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 84, Line: 2, Col: 25},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 79, Line: 2, Col: 20},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 88, Line: 2, Col: 29},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 60, Line: 2, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 92, Line: 3, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: doctype\",\n\t\t\tinput: `templ Name() {\n<!DOCTYPE html>\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 32, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   12,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&DocType{\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 15, Line: 1, Col: 0},\n\t\t\t\t\t\t\tTo:   Position{Index: 30, Line: 1, Col: 15},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"html\",\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 31,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: incomplete open tag\",\n\t\t\tinput: `templ Name() {\n\t\t\t\t        <div\n\t\t\t\t\t\t{\"some string\"}\n\t\t\t\t\t</div>\n}`,\n\t\t\texpected:    &HTMLTemplate{},\n\t\t\texpectError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"template: can contain inline templ elements\",\n\t\t\tinput: `templ x() {\n <a href=\"/\"> @Icon(\"home\", Inline) Home</a>\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 58, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"x()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   9,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 13,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \" \"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"a\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 14, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 15, Line: 1, Col: 3},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"/\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"href\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 16, Line: 1, Col: 4},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 20, Line: 1, Col: 8},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 16, Line: 1, Col: 4},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 24, Line: 1, Col: 12},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 25,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   13,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 26,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \" \"},\n\t\t\t\t\t\t\t&TemplElementExpression{\n\t\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\t\tValue: `Icon(\"home\", Inline)`,\n\t\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\t\tIndex: 47,\n\t\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\t\tCol:   35,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 26, Line: 1, Col: 14},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 47, Line: 1, Col: 35},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 47,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   35,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 48,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   36,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \" \"},\n\t\t\t\t\t\t\t&Text{\n\t\t\t\t\t\t\t\tValue: \"Home\",\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 48, Line: 1, Col: 36},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 52, Line: 1, Col: 40},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 57, Line: 2, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: can contain single line comments\",\n\t\t\tinput: `templ x() {\n\t// Comment\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 25, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"x()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 13,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&GoComment{\n\t\t\t\t\t\tContents:  \" Comment\",\n\t\t\t\t\t\tMultiline: false,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 23, Line: 1, Col: 11},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 23,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 24,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: can contain block comments on the same line\",\n\t\t\tinput: `templ x() {\n\t/* Comment */\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 28, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"x()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 13,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&GoComment{\n\t\t\t\t\t\tContents:  \" Comment \",\n\t\t\t\t\t\tMultiline: true,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 26, Line: 1, Col: 14},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 26,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 27,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: can contain block comments on multiple lines\",\n\t\t\tinput: `templ x() {\n\t/* Line 1\n\t\t Line 2\n\t*/\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 38, Line: 4, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"x()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 13,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&GoComment{\n\t\t\t\t\t\tContents:  \" Line 1\\n\\t\\t Line 2\\n\\t\",\n\t\t\t\t\t\tMultiline: true,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 36, Line: 3, Col: 3},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 36,\n\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 37,\n\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: can contain HTML comments\",\n\t\t\tinput: `templ x() {\n\t<!-- Single line -->\n\t<!--\n\t\tMultiline\n\t-->\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 58, Line: 5, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"x()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 12,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 13,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&HTMLComment{\n\t\t\t\t\t\tContents: \" Single line \",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 13, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 33, Line: 1, Col: 21},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 33,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   21,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\\t\"},\n\t\t\t\t\t&HTMLComment{\n\t\t\t\t\t\tContents: \"\\n\\t\\tMultiline\\n\\t\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 35, Line: 2, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 56, Line: 4, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 56,\n\t\t\t\t\t\t\tLine:  4,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 57,\n\t\t\t\t\t\t\tLine:  5,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: containing spread attributes and children expression\",\n\t\t\tinput: `templ Name(children templ.Attributes) {\n\t\t<span { children... }>\n\t\t\t{ children... }\n\t\t</span>\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 95, Line: 4, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name(children templ.Attributes)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 6,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   6,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 37,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   37,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 40,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 42,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\\t\"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"span\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 43, Line: 1, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 47, Line: 1, Col: 7},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAttributes: []Attribute{&SpreadAttributes{\n\t\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\t\tValue: \"children\",\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 50,\n\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\tCol:   10,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\t\tIndex: 58,\n\t\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\t\tCol:   18,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{Index: 48, Line: 1, Col: 8},\n\t\t\t\t\t\t\t\tTo:   Position{Index: 63, Line: 1, Col: 23},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 64,\n\t\t\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\t\t\tCol:   24,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 68,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\n\\t\\t\\t\"},\n\t\t\t\t\t\t\t&ChildrenExpression{\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 68, Line: 2, Col: 3},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 83, Line: 2, Col: 18},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\t\t\tIndex: 83,\n\t\t\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\t\t\tCol:   18,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\t\t\tIndex: 86,\n\t\t\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tValue: \"\\n\\t\\t\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIndentChildren: true,\n\t\t\t\t\t\tTrailingSpace:  SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 42, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 94, Line: 4, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"template: void element closers are ignored\",\n\t\t\tinput: `templ Name() {\n\t<br></br><br>\n}`,\n\t\t\texpected: &HTMLTemplate{\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 31, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Name()\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   0,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\t\"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"br\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 17, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 19, Line: 1, Col: 4},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceNone,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 16, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 25, Line: 1, Col: 10},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"br\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 26, Line: 1, Col: 11},\n\t\t\t\t\t\t\tTo:   Position{Index: 28, Line: 1, Col: 13},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 25, Line: 1, Col: 10},\n\t\t\t\t\t\t\tTo:   Position{Index: 30, Line: 2, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, matched, err := template.Parse(input)\n\t\t\tdiff := cmp.Diff(tt.expected, actual)\n\t\t\tswitch {\n\t\t\tcase tt.expectError && err == nil:\n\t\t\t\tt.Errorf(\"expected an error got nil: %+v\", actual)\n\t\t\tcase !tt.expectError && err != nil:\n\t\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t\tcase !tt.expectError && diff != \"\":\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Error(\"expected match, but got no match\")\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTemplateParserErrors(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname: \"template: containing element\",\n\t\t\tinput: `templ Name(p Parameter) {\n<span\n}`,\n\t\t\texpected: \"<span>: malformed open element: line 3, col 0\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, matched, err := template.Parse(input)\n\t\t\tif err == nil {\n\t\t\t\tt.Fatalf(\"expected error %q, got nil\", tt.expected)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Error(\"expected match, because there is a partial template\")\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, err.Error()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/templelementparser.go",
    "content": "package parser\n\nimport (\n\t\"github.com/a-h/parse\"\n\t\"github.com/a-h/templ/parser/v2/goexpression\"\n)\n\ntype templElementExpressionParser struct{}\n\nfunc (p templElementExpressionParser) Parse(pi *parse.Input) (n Node, matched bool, err error) {\n\tstart := pi.Position()\n\n\t// Check the prefix first.\n\tif _, matched, err = parse.Rune('@').Parse(pi); err != nil || !matched {\n\t\treturn nil, false, nil\n\t}\n\n\t// Parse the Go expression.\n\tr := &TemplElementExpression{}\n\tif r.Expression, err = parseGo(\"templ element\", pi, goexpression.TemplExpression); err != nil {\n\t\treturn r, true, err\n\t}\n\n\t// Once we've got a start expression, check to see if there's an open brace for children. {\\n.\n\tvar hasOpenBrace bool\n\t_, hasOpenBrace, err = openBraceWithOptionalPadding.Parse(pi)\n\tif err != nil {\n\t\treturn\n\t}\n\tif !hasOpenBrace {\n\t\tr.Range = NewRange(start, pi.Position())\n\t\treturn r, true, nil\n\t}\n\n\t// Once we've had the start of an element's children, we must conclude the block.\n\n\t// Node contents.\n\tnp := newTemplateNodeParser(closeBraceWithOptionalPadding, \"templ element closing brace\")\n\tvar nodes Nodes\n\tif nodes, matched, err = np.Parse(pi); err != nil || !matched {\n\t\t// Populate the nodes anyway, so that the LSP can use them.\n\t\tr.Children = nodes.Nodes\n\t\terr = parse.Error(\"@\"+r.Expression.Value+\": expected nodes, but none were found\", pi.Position())\n\t\treturn r, true, err\n\t}\n\tr.Children = nodes.Nodes\n\n\t// Read the required closing brace.\n\tif _, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !matched {\n\t\terr = parse.Error(\"@\"+r.Expression.Value+\": missing end (expected '}')\", pi.Position())\n\t\treturn r, true, err\n\t}\n\n\tr.Range = NewRange(start, pi.Position())\n\n\treturn r, true, nil\n}\n\nvar templElementExpression templElementExpressionParser\n"
  },
  {
    "path": "parser/v2/templelementparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestTemplElementExpressionParser(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *TemplElementExpression\n\t}{\n\t\t{\n\t\t\tname:  \"templelement: simple\",\n\t\t\tinput: `@Other(p.Test)` + \"\\n\",\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 14, Line: 0, Col: 14},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: simple with underscore\",\n\t\t\tinput: `@Other_Component(p.Test)` + \"\\n\",\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other_Component(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 24,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   24,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 24, Line: 0, Col: 24},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"templelement: simple multiline call\",\n\t\t\tinput: `@Other_Component(\n\t\t\t\tp.Test,\n\t\t\t\t\"something\" + \"else\",\n\t\t\t)` + \"\\n\",\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `Other_Component(\n\t\t\t\tp.Test,\n\t\t\t\t\"something\" + \"else\",\n\t\t\t)`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 60,\n\t\t\t\t\t\t\tLine:  3,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 60, Line: 3, Col: 4},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"templelement: simple, block with text\",\n\t\t\tinput: `@Other(p.Test) {\n\tsome words\n}`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 18,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\\t\"},\n\t\t\t\t\t&Text{\n\t\t\t\t\t\tValue: \"some words\",\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 18, Line: 1, Col: 1},\n\t\t\t\t\t\t\tTo:   Position{Index: 28, Line: 1, Col: 11},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 30, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"templelement: simple, block with anchor\",\n\t\t\tinput: `@Other(p.Test){\n\t\t\t<a href=\"someurl\" />\n\t\t}`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 19,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\\t\\t\\t\"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"a\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 20, Line: 1, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 21, Line: 1, Col: 5},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAttributes: []Attribute{\n\t\t\t\t\t\t\t&ConstantAttribute{\n\t\t\t\t\t\t\t\tValue: \"someurl\",\n\t\t\t\t\t\t\t\tKey: ConstantAttributeKey{\n\t\t\t\t\t\t\t\t\tName: \"href\",\n\t\t\t\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\t\t\t\tFrom: Position{Index: 22, Line: 1, Col: 6},\n\t\t\t\t\t\t\t\t\t\tTo:   Position{Index: 26, Line: 1, Col: 10},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 22, Line: 1, Col: 6},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 36, Line: 1, Col: 20},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 19, Line: 1, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 42, Line: 2, Col: 2},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 43, Line: 2, Col: 3},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"templelement: simple, block with templelement as child\",\n\t\t\tinput: `@Other(p.Test) {\n\t\t\t\t@other2\n\t\t\t}`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: \"Other(p.Test)\",\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 14,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   14,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 16,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   16,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 21,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   4,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\\t\\t\\t\\t\"},\n\t\t\t\t\t&TemplElementExpression{\n\t\t\t\t\t\tExpression: Expression{\n\t\t\t\t\t\t\tValue: \"other2\",\n\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\tFrom: Position{22, 1, 5},\n\t\t\t\t\t\t\t\tTo:   Position{28, 1, 11},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 21, Line: 1, Col: 4},\n\t\t\t\t\t\t\tTo:   Position{Index: 28, Line: 1, Col: 11},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 28,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   11,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 32,\n\t\t\t\t\t\t\tLine:  2,\n\t\t\t\t\t\t\tCol:   3,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n\\t\\t\\t\"},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 33, Line: 2, Col: 4},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"templelement: can parse the initial expression and leave the text\",\n\t\t\tinput: `@Icon(\"home\", Inline) Home</a>\n}`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `Icon(\"home\", Inline)`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 21,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   21,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 21, Line: 0, Col: 21},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: supports the use of templ elements in other packages\",\n\t\t\tinput: `@templates.Icon(\"home\", Inline)`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `templates.Icon(\"home\", Inline)`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 31,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   31,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 31, Line: 0, Col: 31},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: supports the use of params which contain braces and params\",\n\t\t\tinput: `@templates.New(test{}, other())`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `templates.New(test{}, other())`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 31,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   31,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 31, Line: 0, Col: 31},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: supports a slice of functions\",\n\t\t\tinput: `@templates[0]()`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `templates[0]()`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 15,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   15,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 15, Line: 0, Col: 15},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: supports a map of functions\",\n\t\t\tinput: `@templates[\"key\"]()`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `templates[\"key\"]()`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 19,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   19,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 19, Line: 0, Col: 19},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: supports a slice of structs/interfaces\",\n\t\t\tinput: `@templates[0].CreateTemplate()`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `templates[0].CreateTemplate()`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   30,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 30, Line: 0, Col: 30},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: supports a slice of structs/interfaces\",\n\t\t\tinput: `@templates[0].CreateTemplate()`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `templates[0].CreateTemplate()`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 30,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   30,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 30, Line: 0, Col: 30},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: bare variables are read until the end of the token\",\n\t\t\tinput: `@template</div>`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `template`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 1,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 9,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   9,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 9, Line: 0, Col: 9},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"templelement: struct literal method calls are supported\",\n\t\t\tinput: `@layout.DefaultLayout{}.Compile()<div>`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `layout.DefaultLayout{}.Compile()`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{1, 0, 1},\n\t\t\t\t\t\tTo:   Position{33, 0, 33},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 33, Line: 0, Col: 33},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"templelement: struct literal method calls are supported, with child elements\",\n\t\t\tinput: `@layout.DefaultLayout{}.Compile() {\n  <div>hello</div>\n}`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `layout.DefaultLayout{}.Compile()`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{1, 0, 1},\n\t\t\t\t\t\tTo:   Position{33, 0, 33},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tChildren: []Node{\n\t\t\t\t\t&Whitespace{Range: Range{\n\t\t\t\t\t\tFrom: Position{\n\t\t\t\t\t\t\tIndex: 35,\n\t\t\t\t\t\t\tLine:  0,\n\t\t\t\t\t\t\tCol:   35,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTo: Position{\n\t\t\t\t\t\t\tIndex: 38,\n\t\t\t\t\t\t\tLine:  1,\n\t\t\t\t\t\t\tCol:   2,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\tValue: \"\\n  \"},\n\t\t\t\t\t&Element{\n\t\t\t\t\t\tName: \"div\",\n\t\t\t\t\t\tNameRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 39, Line: 1, Col: 3},\n\t\t\t\t\t\t\tTo:   Position{Index: 42, Line: 1, Col: 6},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tChildren: []Node{\n\t\t\t\t\t\t\t&Text{\n\t\t\t\t\t\t\t\tValue: \"hello\",\n\t\t\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\t\t\tFrom: Position{Index: 43, Line: 1, Col: 7},\n\t\t\t\t\t\t\t\t\tTo:   Position{Index: 48, Line: 1, Col: 12},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTrailingSpace: SpaceVertical,\n\t\t\t\t\t\tRange: Range{\n\t\t\t\t\t\t\tFrom: Position{Index: 38, Line: 1, Col: 2},\n\t\t\t\t\t\t\tTo:   Position{Index: 55, Line: 2, Col: 0},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 56, Line: 2, Col: 1},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"templelement: arguments can receive a slice of complex types\",\n\t\t\tinput: `@tabs([]*TabData{\n  {Name: \"A\"},\n  {Name: \"B\"},\n})`,\n\t\t\texpected: &TemplElementExpression{\n\t\t\t\tExpression: Expression{\n\t\t\t\t\tValue: `tabs([]*TabData{\n  {Name: \"A\"},\n  {Name: \"B\"},\n})`,\n\t\t\t\t\tRange: Range{\n\t\t\t\t\t\tFrom: Position{1, 0, 1},\n\t\t\t\t\t\tTo:   Position{50, 3, 2},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 50, Line: 3, Col: 2},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, matched, err := templElementExpression.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTemplElementExpressionParserFailures(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\tinput string\n\t}{\n\t\t{\n\t\t\tname: \"templelement: missing closing brace\",\n\t\t\tinput: `@SplitRule(types.GroupMember{\n    UserID:   uuid.NewString(),\n    Username: \"user me\",\n}, []types.GroupMember{\n    {\n    UserID:   uuid.NewString(),\n    Username: \"user 1\",\n    },\n`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\t_, matched, err := templElementExpression.Parse(input)\n\t\t\tif err == nil {\n\t\t\t\tt.Fatalf(\"expected an error\")\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\tt.Fatalf(\"although we got an error, we did find a templ element, because the text started with @\")\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/testdata/fuzz/FuzzScriptParser/0667fe9c719c304f",
    "content": "go test fuzz v1\nstring(\"<script>/*/00000\\x17I020000000////00000\\x17000\")\n"
  },
  {
    "path": "parser/v2/testdata/fuzz/FuzzScriptParser/21c86d8a2781524b",
    "content": "go test fuzz v1\nstring(\"<script>00000000000000000000////0000000000\")\n"
  },
  {
    "path": "parser/v2/testdata/fuzz/FuzzScriptParser/43cd47dd50874af5",
    "content": "go test fuzz v1\nstring(\"<script>\\n  function showSuccessMessage(responseText) {\\n\\t\\t\\tconst formRespo</scriptcument.getElementById('form-response');\\n\\t\\t\\tformResponse.innerHTML = `\\n\\t\\t\\t\\t<div class=\\\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded\\\">\\n\\t\\t\\t\\t\\t${responseText}\\n\\t\\t\\t\\t</div>`;\\n\\t\\t}\\nnse = do>\")\n"
  },
  {
    "path": "parser/v2/textparser.go",
    "content": "package parser\n\nimport (\n\t\"unicode\"\n\n\t\"github.com/a-h/parse\"\n)\n\nvar tagTemplOrNewLine = parse.Any(parse.Rune('<'), parse.Rune('{'), parse.Rune('}'), parse.String(\"\\r\\n\"), parse.Rune('\\n'))\n\nvar textParser = parse.Func(func(pi *parse.Input) (n Node, ok bool, err error) {\n\tfrom := pi.Position()\n\n\t// Read until a tag or templ expression opens.\n\tt := &Text{}\n\tif t.Value, ok, err = parse.StringUntil(tagTemplOrNewLine).Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\tif isWhitespace(t.Value) {\n\t\treturn t, false, nil\n\t}\n\tif _, ok = pi.Peek(1); !ok {\n\t\terr = parse.Error(\"textParser: unterminated text, expected tag open, templ expression open, or newline\", from)\n\t\treturn\n\t}\n\tt.Range = NewRange(from, pi.Position())\n\n\t// Elide any void element closing tags.\n\tif _, _, err = voidElementCloser.Parse(pi); err != nil {\n\t\treturn\n\t}\n\n\t// Parse trailing whitespace.\n\tws, _, err := parse.Whitespace.Parse(pi)\n\tif err != nil {\n\t\treturn t, false, err\n\t}\n\tt.TrailingSpace, err = NewTrailingSpace(ws)\n\tif err != nil {\n\t\treturn t, false, err\n\t}\n\n\treturn t, true, nil\n})\n\nfunc isWhitespace(s string) bool {\n\tfor _, r := range s {\n\t\tif !unicode.IsSpace(r) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "parser/v2/textparser_test.go",
    "content": "package parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/a-h/parse\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestTextParser(t *testing.T) {\n\tvar tests = []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected *Text\n\t}{\n\t\t{\n\t\t\tname:  \"Text ends at an element start\",\n\t\t\tinput: `abcdef<a href=\"https://example.com\">More</a>`,\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"abcdef\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Text ends at a templ expression start\",\n\t\t\tinput: `abcdef{ \"test\" }`,\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"abcdef\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Text may contain spaces\",\n\t\t\tinput: `abcdef ghijk{ \"test\" }`,\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"abcdef ghijk\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 12, Line: 0, Col: 12},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Text may contain named references\",\n\t\t\tinput: `abcdef&nbsp;ghijk{ \"test\" }`,\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"abcdef&nbsp;ghijk\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Text may contain base 10 numeric references\",\n\t\t\tinput: `abcdef&#32;ghijk{ \"test\" }`,\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"abcdef&#32;ghijk\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 16, Line: 0, Col: 16},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Text may contain hexadecimal numeric references\",\n\t\t\tinput: `abcdef&#x20;ghijk{ \"test\" }`,\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"abcdef&#x20;ghijk\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 17, Line: 0, Col: 17},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Multiline text is collected line by line\",\n\t\t\tinput: \"Line 1\\nLine 2\",\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"Line 1\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\tTrailingSpace: \"\\n\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Multiline text is collected line by line (Windows)\",\n\t\t\tinput: \"Line 1\\r\\nLine 2\",\n\t\t\texpected: &Text{\n\t\t\t\tValue: \"Line 1\",\n\t\t\t\tRange: Range{\n\t\t\t\t\tFrom: Position{Index: 0, Line: 0, Col: 0},\n\t\t\t\t\tTo:   Position{Index: 6, Line: 0, Col: 6},\n\t\t\t\t},\n\t\t\t\tTrailingSpace: \"\\n\",\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tinput := parse.NewInput(tt.input)\n\t\t\tactual, ok, err := textParser.Parse(input)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"unexpected failure for input %q\", tt.input)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "parser/v2/types.go",
    "content": "package parser\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"go/format\"\n\t\"io\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/a-h/parse\"\n)\n\n// package parser\n//\n// import \"strings\"\n// import strs \"strings\"\n//\n// css AddressLineStyle() {\n//   background-color: #ff0000;\n//   color: #ffffff;\n// }\n//\n// templ RenderAddress(addr Address) {\n// \t<div style={ AddressLineStyle() }>{ addr.Address1 }</div>\n// \t<div>{ addr.Address2 }</div>\n// \t<div>{ addr.Address3 }</div>\n// \t<div>{ addr.Address4 }</div>\n// }\n//\n// templ Render(p Person) {\n//    <div>\n//      <div>{ p.Name() }</div>\n//      <a href={ p.URL }>{ strings.ToUpper(p.Name()) }</a>\n//      <div>\n//          if p.Type == \"test\" {\n//             <span>{ \"Test user\" }</span>\n//          } else {\n// \t    \t<span>{ \"Not test user\" }</span>\n//          }\n//          for _, v := range p.Addresses {\n//             {! call RenderAddress(v) }\n//          }\n//      </div>\n//    </div>\n// }\n\n// Source mapping to map from the source code of the template to the\n// in-memory representation.\ntype Position struct {\n\tIndex int64\n\tLine  uint32\n\tCol   uint32\n}\n\nfunc (p *Position) String() string {\n\treturn fmt.Sprintf(\"line %d, col %d (index %d)\", p.Line, p.Col, p.Index)\n}\n\n// NewPosition initialises a position.\nfunc NewPosition(index int64, line, col uint32) Position {\n\treturn Position{\n\t\tIndex: index,\n\t\tLine:  line,\n\t\tCol:   col,\n\t}\n}\n\n// NewExpression creates a Go expression.\nfunc NewExpression(value string, from, to parse.Position) Expression {\n\treturn Expression{\n\t\tValue: value,\n\t\tRange: Range{\n\t\t\tFrom: Position{\n\t\t\t\tIndex: int64(from.Index),\n\t\t\t\tLine:  uint32(from.Line),\n\t\t\t\tCol:   uint32(from.Col),\n\t\t\t},\n\t\t\tTo: Position{\n\t\t\t\tIndex: int64(to.Index),\n\t\t\t\tLine:  uint32(to.Line),\n\t\t\t\tCol:   uint32(to.Col),\n\t\t\t},\n\t\t},\n\t}\n}\n\n// NewRange creates a Range expression.\nfunc NewRange(from, to parse.Position) Range {\n\treturn Range{\n\t\tFrom: Position{\n\t\t\tIndex: int64(from.Index),\n\t\t\tLine:  uint32(from.Line),\n\t\t\tCol:   uint32(from.Col),\n\t\t},\n\t\tTo: Position{\n\t\t\tIndex: int64(to.Index),\n\t\t\tLine:  uint32(to.Line),\n\t\t\tCol:   uint32(to.Col),\n\t\t},\n\t}\n}\n\n// Range of text within a file.\ntype Range struct {\n\tFrom Position\n\tTo   Position\n}\n\n// Expression containing Go code.\ntype Expression struct {\n\tValue string\n\tRange Range\n}\n\ntype TemplateFile struct {\n\t// Header contains comments or whitespace at the top of the file.\n\tHeader []*TemplateFileGoExpression\n\t// Package expression.\n\tPackage Package\n\t// Filepath is where the file was loaded from. It is not always available.\n\tFilepath string\n\t// Nodes in the file.\n\tNodes []TemplateFileNode\n}\n\nfunc (tf *TemplateFile) Write(w io.Writer) error {\n\tfor _, n := range tf.Header {\n\t\tif err := n.Write(w, 0); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tvar indent int\n\tif err := tf.Package.Write(w, indent); err != nil {\n\t\treturn err\n\t}\n\tif _, err := io.WriteString(w, \"\\n\\n\"); err != nil {\n\t\treturn err\n\t}\n\tfor i, n := range tf.Nodes {\n\t\tif err := n.Write(w, indent); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := io.WriteString(w, getNodeWhitespace(tf.Nodes, i)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (tf *TemplateFile) Visit(v Visitor) error {\n\treturn v.VisitTemplateFile(tf)\n}\n\nfunc getNodeWhitespace(nodes []TemplateFileNode, i int) string {\n\tif i == len(nodes)-1 {\n\t\treturn \"\\n\"\n\t}\n\tif _, nextIsTemplate := nodes[i+1].(*HTMLTemplate); nextIsTemplate {\n\t\tif e, isGo := nodes[i].(*TemplateFileGoExpression); isGo && endsWithComment(e.Expression.Value) {\n\t\t\treturn \"\\n\"\n\t\t}\n\t}\n\treturn \"\\n\\n\"\n}\n\nfunc endsWithComment(s string) bool {\n\tlineSlice := strings.Split(s, \"\\n\")\n\treturn strings.HasPrefix(lineSlice[len(lineSlice)-1], \"//\")\n}\n\n// TemplateFileNode can be a Template, CSS, Script or Go.\ntype TemplateFileNode interface {\n\tIsTemplateFileNode() bool\n\tWrite(w io.Writer, indent int) error\n\tVisit(v Visitor) error\n}\n\n// TemplateFileGoExpression within a TemplateFile\ntype TemplateFileGoExpression struct {\n\tExpression    Expression\n\tBeforePackage bool\n}\n\nfunc (exp *TemplateFileGoExpression) IsTemplateFileNode() bool { return true }\nfunc (exp *TemplateFileGoExpression) Write(w io.Writer, indent int) error {\n\tin := exp.Expression.Value\n\n\tif exp.BeforePackage {\n\t\tin += \"\\\\\\\\formatstring\\npackage p\\n\\\\\\\\formatstring\"\n\t}\n\tdata, err := format.Source([]byte(in))\n\tif err != nil {\n\t\treturn writeIndent(w, indent, exp.Expression.Value)\n\t}\n\tif exp.BeforePackage {\n\t\tdata = bytes.TrimSuffix(data, []byte(\"\\\\\\\\formatstring\\npackage p\\n\\\\\\\\formatstring\"))\n\t}\n\t_, err = w.Write(data)\n\treturn err\n}\n\nfunc (exp *TemplateFileGoExpression) Visit(v Visitor) error {\n\treturn v.VisitTemplateFileGoExpression(exp)\n}\n\nfunc writeIndent(w io.Writer, level int, s ...string) (err error) {\n\tindent := strings.Repeat(\"\\t\", level)\n\tif _, err = io.WriteString(w, indent); err != nil {\n\t\treturn err\n\t}\n\tfor _, ss := range s {\n\t\t_, err = io.WriteString(w, ss)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\ntype Package struct {\n\tExpression Expression\n}\n\nfunc (p *Package) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, p.Expression.Value)\n}\n\nfunc (p *Package) Visit(v Visitor) error {\n\treturn v.VisitPackage(p)\n}\n\n// Whitespace.\ntype Whitespace struct {\n\tRange Range\n\tValue string\n}\n\nfunc (ws *Whitespace) IsNode() bool { return true }\n\nfunc (ws *Whitespace) Write(w io.Writer, indent int) error {\n\tif ws.Value == \"\" || !strings.Contains(ws.Value, \"\\n\") {\n\t\treturn nil\n\t}\n\t// https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace\n\t// - All spaces and tabs immediately before and after a line break are ignored.\n\t// - All tab characters are handled as space characters.\n\t// - Line breaks are converted to spaces.\n\t// Any space immediately following another space (even across two separate inline elements) is ignored.\n\t// Sequences of spaces at the beginning and end of an element are removed.\n\n\t// Notes: Since we only have whitespace in this node, we can strip anything that isn't a line break.\n\t// Since any space following another space is ignored, we can collapse to a single rule.\n\t// So, the rule is... if there's a newline, it becomes a single space, or it's stripped.\n\t// We have to remove the start and end space elsewhere.\n\t_, err := io.WriteString(w, \" \")\n\treturn err\n}\n\nfunc (ws *Whitespace) Visit(v Visitor) error {\n\treturn v.VisitWhitespace(ws)\n}\n\n// CSS definition.\n//\n//\tcss Name() {\n//\t  color: #ffffff;\n//\t  background-color: { constants.BackgroundColor };\n//\t  background-image: url('./somewhere.png');\n//\t}\ntype CSSTemplate struct {\n\tRange      Range\n\tName       string\n\tExpression Expression\n\tProperties []CSSProperty\n}\n\nfunc (css *CSSTemplate) IsTemplateFileNode() bool { return true }\nfunc (css *CSSTemplate) Write(w io.Writer, indent int) error {\n\tsource := formatFunctionArguments(css.Expression.Value)\n\tif err := writeIndent(w, indent, \"css \", string(source), \" {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tfor _, p := range css.Properties {\n\t\tif err := p.Write(w, indent+1); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (css *CSSTemplate) Visit(v Visitor) error {\n\treturn v.VisitCSSTemplate(css)\n}\n\n// CSSProperty is a CSS property and value pair.\ntype CSSProperty interface {\n\tIsCSSProperty() bool\n\tWrite(w io.Writer, indent int) error\n\tVisit(v Visitor) error\n}\n\n// color: #ffffff;\ntype ConstantCSSProperty struct {\n\tName  string\n\tValue string\n}\n\nfunc (c *ConstantCSSProperty) IsCSSProperty() bool { return true }\nfunc (c *ConstantCSSProperty) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, c.String(false)); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (c ConstantCSSProperty) String(minified bool) string {\n\tsb := new(strings.Builder)\n\tsb.WriteString(c.Name)\n\tif minified {\n\t\tsb.WriteString(\":\")\n\t} else {\n\t\tsb.WriteString(\": \")\n\t}\n\tsb.WriteString(c.Value)\n\tsb.WriteString(\";\")\n\tif !minified {\n\t\tsb.WriteString(\"\\n\")\n\t}\n\treturn sb.String()\n}\n\nfunc (c *ConstantCSSProperty) Visit(v Visitor) error {\n\treturn v.VisitConstantCSSProperty(c)\n}\n\n// background-color: { constants.BackgroundColor };\ntype ExpressionCSSProperty struct {\n\tName  string\n\tValue *StringExpression\n}\n\nfunc (c *ExpressionCSSProperty) IsCSSProperty() bool { return true }\nfunc (c *ExpressionCSSProperty) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, c.Name, \": \"); err != nil {\n\t\treturn err\n\t}\n\tif err := c.Value.Write(w, 0); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.Write([]byte(\";\\n\")); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (c *ExpressionCSSProperty) Visit(v Visitor) error {\n\treturn v.VisitExpressionCSSProperty(c)\n}\n\n// <!DOCTYPE html>\ntype DocType struct {\n\tRange Range\n\tValue string\n}\n\nfunc (dt *DocType) IsNode() bool { return true }\nfunc (dt *DocType) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, \"<!DOCTYPE \", dt.Value, \">\")\n}\n\nfunc (dt *DocType) Visit(v Visitor) error {\n\treturn v.VisitDocType(dt)\n}\n\n// HTMLTemplate definition.\n//\n//\ttempl Name(p Parameter) {\n//\t  if ... {\n//\t      <Element></Element>\n//\t  }\n//\t}\ntype HTMLTemplate struct {\n\tRange      Range\n\tExpression Expression\n\tChildren   []Node\n}\n\nfunc (t *HTMLTemplate) IsTemplateFileNode() bool { return true }\n\nfunc (t *HTMLTemplate) Write(w io.Writer, indent int) error {\n\tsource := formatFunctionArguments(t.Expression.Value)\n\tif err := writeIndent(w, indent, \"templ \", string(source), \" {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err := writeNodesIndented(w, indent+1, t.Children); err != nil {\n\t\treturn err\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (t *HTMLTemplate) Visit(v Visitor) error {\n\treturn v.VisitHTMLTemplate(t)\n}\n\n// TrailingSpace defines the whitespace that may trail behind the close of an element, a\n// text node, or string expression.\ntype TrailingSpace string\n\nconst (\n\tSpaceNone       TrailingSpace = \"\"\n\tSpaceHorizontal TrailingSpace = \" \"\n\tSpaceVertical   TrailingSpace = \"\\n\"\n)\n\nvar ErrNonSpaceCharacter = errors.New(\"non space character found\")\n\nfunc NewTrailingSpace(s string) (ts TrailingSpace, err error) {\n\tvar hasHorizontalSpace bool\n\tfor _, r := range s {\n\t\tif r == '\\n' {\n\t\t\treturn SpaceVertical, nil\n\t\t}\n\t\tif unicode.IsSpace(r) {\n\t\t\thasHorizontalSpace = true\n\t\t\tcontinue\n\t\t}\n\t\treturn ts, ErrNonSpaceCharacter\n\t}\n\tif hasHorizontalSpace {\n\t\treturn SpaceHorizontal, nil\n\t}\n\treturn SpaceNone, nil\n}\n\ntype Nodes struct {\n\tNodes []Node\n}\n\n// A Node appears within a template, e.g. an StringExpression, Element, IfExpression etc.\ntype Node interface {\n\tIsNode() bool\n\t// Write out the string*.\n\tWrite(w io.Writer, indent int) error\n\tVisit(v Visitor) error\n}\n\ntype CompositeNode interface {\n\tNode\n\tChildNodes() []Node\n}\n\ntype WhitespaceTrailer interface {\n\tTrailing() TrailingSpace\n}\n\nvar (\n\t_ WhitespaceTrailer = (*Element)(nil)\n\t_ WhitespaceTrailer = (*Text)(nil)\n\t_ WhitespaceTrailer = (*StringExpression)(nil)\n)\n\n// Text node within the document.\ntype Text struct {\n\t// Range of the text within the templ file.\n\tRange Range\n\t// Value is the raw HTML encoded value.\n\tValue string\n\t// TrailingSpace lists what happens after the text.\n\tTrailingSpace TrailingSpace\n}\n\nfunc (t Text) Trailing() TrailingSpace {\n\treturn t.TrailingSpace\n}\n\nfunc (t *Text) IsNode() bool { return true }\nfunc (t *Text) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, t.Value)\n}\n\nfunc (t *Text) Visit(v Visitor) error {\n\treturn v.VisitText(t)\n}\n\n// <a .../> or <div ...>...</div>\ntype Element struct {\n\tName           string\n\tAttributes     []Attribute\n\tIndentAttrs    bool\n\tChildren       []Node\n\tIndentChildren bool\n\tTrailingSpace  TrailingSpace\n\tNameRange      Range\n\tRange          Range\n}\n\nfunc (e Element) Trailing() TrailingSpace {\n\treturn e.TrailingSpace\n}\n\nfunc (e *Element) Visit(v Visitor) error {\n\treturn v.VisitElement(e)\n}\n\nvar voidElements = map[string]struct{}{\n\t\"area\": {}, \"base\": {}, \"br\": {}, \"col\": {}, \"command\": {}, \"embed\": {}, \"hr\": {}, \"img\": {}, \"input\": {}, \"keygen\": {}, \"link\": {}, \"meta\": {}, \"param\": {}, \"source\": {}, \"track\": {}, \"wbr\": {},\n}\n\n// https://www.w3.org/TR/2011/WD-html-markup-20110113/syntax.html#void-element\nfunc (e Element) IsVoidElement() bool {\n\t_, ok := voidElements[e.Name]\n\treturn ok\n}\n\nfunc (e Element) hasNonWhitespaceChildren() bool {\n\tfor _, c := range e.Children {\n\t\tif _, isWhitespace := c.(*Whitespace); !isWhitespace {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nvar blockElements = map[string]struct{}{\n\t\"address\": {}, \"article\": {}, \"aside\": {}, \"body\": {}, \"blockquote\": {}, \"canvas\": {}, \"dd\": {}, \"div\": {}, \"dl\": {}, \"dt\": {}, \"fieldset\": {}, \"figcaption\": {}, \"figure\": {}, \"footer\": {}, \"form\": {}, \"h1\": {}, \"h2\": {}, \"h3\": {}, \"h4\": {}, \"h5\": {}, \"h6\": {}, \"head\": {}, \"header\": {}, \"hr\": {}, \"html\": {}, \"li\": {}, \"main\": {}, \"meta\": {}, \"nav\": {}, \"noscript\": {}, \"ol\": {}, \"p\": {}, \"pre\": {}, \"script\": {}, \"section\": {}, \"table\": {}, \"template\": {}, \"tfoot\": {}, \"turbo-stream\": {}, \"ul\": {}, \"video\": {},\n\t// Not strictly block but for the purposes of layout, they are.\n\t\"title\": {}, \"style\": {}, \"link\": {}, \"td\": {}, \"th\": {}, \"tr\": {}, \"br\": {},\n}\n\nfunc (e Element) IsBlockElement() bool {\n\t_, ok := blockElements[e.Name]\n\treturn ok\n}\n\n// Validate that no invalid expressions have been used.\nfunc (e Element) Validate() (msgs []string, ok bool) {\n\t// Validate that style tags don't contain expressions.\n\tif strings.EqualFold(e.Name, \"style\") {\n\t\tif containsNonTextNodes(e.Children) {\n\t\t\tmsgs = append(msgs, \"invalid node contents: style elements must only contain text\")\n\t\t}\n\t}\n\treturn msgs, len(msgs) == 0\n}\n\nfunc containsNonTextNodes(nodes []Node) bool {\n\tfor _, n := range nodes {\n\t\tswitch n.(type) {\n\t\tcase *Text:\n\t\t\tcontinue\n\t\tcase *Whitespace:\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (e Element) ChildNodes() []Node {\n\treturn e.Children\n}\nfunc (e *Element) IsNode() bool { return true }\nfunc (e *Element) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, \"<\", e.Name); err != nil {\n\t\treturn err\n\t}\n\tfor i := range e.Attributes {\n\t\ta := e.Attributes[i]\n\t\t// Only the conditional attributes get indented.\n\t\tvar attrIndent int\n\t\tif e.IndentAttrs {\n\t\t\tif _, err := w.Write([]byte(\"\\n\")); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tattrIndent = indent + 1\n\t\t} else {\n\t\t\tif _, err := w.Write([]byte(\" \")); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err := a.Write(w, attrIndent); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tvar closeAngleBracketIndent int\n\tif e.IndentAttrs {\n\t\tif _, err := w.Write([]byte(\"\\n\")); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcloseAngleBracketIndent = indent\n\t}\n\tif e.hasNonWhitespaceChildren() {\n\t\tif e.IndentChildren {\n\t\t\tif err := writeIndent(w, closeAngleBracketIndent, \">\\n\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := writeNodesIndented(w, indent+1, e.Children); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := writeIndent(w, indent, \"</\", e.Name, \">\"); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tif err := writeIndent(w, closeAngleBracketIndent, \">\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := writeNodesWithoutIndentation(w, e.Children); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := w.Write([]byte(\"</\" + e.Name + \">\")); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\tif e.IsVoidElement() {\n\t\tif err := writeIndent(w, closeAngleBracketIndent, \"/>\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\tif err := writeIndent(w, closeAngleBracketIndent, \"></\", e.Name, \">\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc writeNodesWithoutIndentation(w io.Writer, nodes []Node) error {\n\treturn writeNodes(w, 0, nodes, false)\n}\n\nfunc writeNodesIndented(w io.Writer, level int, nodes []Node) error {\n\treturn writeNodes(w, level, nodes, true)\n}\n\nfunc writeNodes(w io.Writer, level int, nodes []Node, indent bool) error {\n\tstartLevel := level\n\tfor i, n := range nodes {\n\t\t// Skip whitespace nodes.\n\t\tif _, isWhitespace := n.(*Whitespace); isWhitespace {\n\t\t\tcontinue\n\t\t}\n\t\tif err := n.Write(w, level); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Apply trailing whitespace if present.\n\t\ttrailing := SpaceVertical\n\t\tif wst, isWhitespaceTrailer := n.(WhitespaceTrailer); isWhitespaceTrailer {\n\t\t\ttrailing = wst.Trailing()\n\t\t}\n\t\t// Put a newline after the last node in indentation mode.\n\t\tif indent && ((nextNodeIsBlock(nodes, i) || i == len(nodes)-1) || shouldAlwaysBreakAfter(n)) {\n\t\t\ttrailing = SpaceVertical\n\t\t}\n\t\tswitch trailing {\n\t\tcase SpaceNone:\n\t\t\tlevel = 0\n\t\tcase SpaceHorizontal:\n\t\t\tlevel = 0\n\t\tcase SpaceVertical:\n\t\t\tlevel = startLevel\n\t\t}\n\t\tif _, err := w.Write([]byte(trailing)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc shouldAlwaysBreakAfter(node Node) bool {\n\tif el, isElement := node.(*Element); isElement {\n\t\treturn strings.EqualFold(el.Name, \"br\") || strings.EqualFold(el.Name, \"hr\")\n\t}\n\treturn false\n}\n\nfunc nextNodeIsBlock(nodes []Node, i int) bool {\n\tif len(nodes)-1 < i+1 {\n\t\treturn false\n\t}\n\treturn isBlockNode(nodes[i+1])\n}\n\nfunc isBlockNode(node Node) bool {\n\tswitch n := node.(type) {\n\tcase *IfExpression:\n\t\treturn true\n\tcase *SwitchExpression:\n\t\treturn true\n\tcase *ForExpression:\n\t\treturn true\n\tcase *Element:\n\t\treturn n.IsBlockElement() || n.IndentChildren\n\t}\n\treturn false\n}\n\nfunc NewScriptContentsScriptCode(value string) ScriptContents {\n\treturn ScriptContents{\n\t\tValue: &value,\n\t}\n}\n\nfunc NewScriptContentsGo(code *GoCode, insideStringLiteral bool) ScriptContents {\n\treturn ScriptContents{\n\t\tGoCode:              code,\n\t\tInsideStringLiteral: insideStringLiteral,\n\t}\n}\n\ntype ScriptContents struct {\n\t// Value is the raw script contents. This is nil if the Type is Go.\n\tValue *string\n\t// GoCode is the Go expression. This is nil if the Type is JS.\n\tGoCode *GoCode\n\t// InsideStringLiteral denotes how the result of any Go expression should be escaped in the output.\n\t//  - Not quoted: JSON encoded.\n\t//  - InsideStringLiteral: JS escaped (newlines become \\n, `\"' becomes \\`\\\"\\' etc.), HTML escaped so that a string can't contain </script>.\n\tInsideStringLiteral bool\n}\n\ntype ScriptElement struct {\n\tAttributes []Attribute\n\tContents   []ScriptContents\n\tRange      Range\n}\n\nfunc (se *ScriptElement) IsNode() bool { return true }\nfunc (se *ScriptElement) Write(w io.Writer, indent int) error {\n\t// Start.\n\tif err := writeIndent(w, indent, \"<script\"); err != nil {\n\t\treturn err\n\t}\n\tfor i := range se.Attributes {\n\t\tif _, err := w.Write([]byte(\" \")); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ta := se.Attributes[i]\n\t\t// Don't indent the attributes, only the conditional attributes get indented.\n\t\tif err := a.Write(w, 0); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif _, err := w.Write([]byte(\">\")); err != nil {\n\t\treturn err\n\t}\n\t// Contents.\n\tfor _, c := range se.Contents {\n\t\tif c.Value != nil {\n\t\t\tif err := writeStrings(w, *c.Value); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\t// Write the expression.\n\t\tif c.GoCode == nil {\n\t\t\treturn errors.New(\"script contents expression is nil\")\n\t\t}\n\t\tif isWhitespace(c.GoCode.Expression.Value) {\n\t\t\tc.GoCode.Expression.Value = \"\"\n\t\t}\n\t\tif err := writeStrings(w, `{{ `, c.GoCode.Expression.Value, ` }}`, string(c.GoCode.TrailingSpace)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Close.\n\tif _, err := w.Write([]byte(\"</script>\")); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (se *ScriptElement) Visit(v Visitor) error {\n\treturn v.VisitScriptElement(se)\n}\n\nfunc writeStrings(w io.Writer, ss ...string) error {\n\tfor _, s := range ss {\n\t\tif _, err := io.WriteString(w, s); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\ntype RawElement struct {\n\tName       string\n\tAttributes []Attribute\n\tContents   string\n\tRange      Range\n}\n\nfunc (e *RawElement) IsNode() bool { return true }\nfunc (e *RawElement) Write(w io.Writer, indent int) error {\n\t// Start.\n\tif err := writeIndent(w, indent, \"<\", e.Name); err != nil {\n\t\treturn err\n\t}\n\tfor _, a := range e.Attributes {\n\t\tif _, err := w.Write([]byte(\" \")); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Don't indent the attributes, only the conditional attributes get indented.\n\t\tif err := a.Write(w, 0); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif _, err := w.Write([]byte(\">\")); err != nil {\n\t\treturn err\n\t}\n\t// Contents.\n\tif _, err := w.Write([]byte(e.Contents)); err != nil {\n\t\treturn err\n\t}\n\t// Close.\n\tif _, err := w.Write([]byte(\"</\" + e.Name + \">\")); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (e *RawElement) Visit(v Visitor) error {\n\treturn v.VisitRawElement(e)\n}\n\ntype Attribute interface {\n\t// Write out the string*.\n\tWrite(w io.Writer, indent int) error\n\tVisit(v Visitor) error\n\tCopy() Attribute\n}\n\ntype AttributeKey interface {\n\tfmt.Stringer\n}\n\ntype ConstantAttributeKey struct {\n\tName      string\n\tNameRange Range\n}\n\nfunc (c ConstantAttributeKey) String() string {\n\treturn c.Name\n}\n\ntype ExpressionAttributeKey struct {\n\tExpression Expression\n}\n\nfunc (e ExpressionAttributeKey) String() string {\n\treturn `{ ` + e.Expression.Value + ` }`\n}\n\n// <hr noshade/>\ntype BoolConstantAttribute struct {\n\tKey   AttributeKey\n\tRange Range\n}\n\nfunc (bca *BoolConstantAttribute) String() string {\n\treturn bca.Key.String()\n}\n\nfunc (bca *BoolConstantAttribute) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, bca.String())\n}\n\nfunc (bca *BoolConstantAttribute) Visit(v Visitor) error {\n\treturn v.VisitBoolConstantAttribute(bca)\n}\n\nfunc (bca *BoolConstantAttribute) Copy() Attribute {\n\treturn &BoolConstantAttribute{\n\t\tKey:   bca.Key,\n\t\tRange: bca.Range,\n\t}\n}\n\n// href=\"\"\ntype ConstantAttribute struct {\n\tKey         AttributeKey\n\tValue       string\n\tSingleQuote bool\n\tRange       Range\n}\n\nfunc (ca *ConstantAttribute) String() string {\n\tquote := `\"`\n\tif ca.SingleQuote {\n\t\tquote = `'`\n\t}\n\treturn ca.Key.String() + `=` + quote + ca.Value + quote\n}\n\nfunc (ca *ConstantAttribute) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, ca.String())\n}\n\nfunc (ca *ConstantAttribute) Visit(v Visitor) error {\n\treturn v.VisitConstantAttribute(ca)\n}\n\nfunc (ca *ConstantAttribute) Copy() Attribute {\n\treturn &ConstantAttribute{\n\t\tValue:       ca.Value,\n\t\tSingleQuote: ca.SingleQuote,\n\t\tKey:         ca.Key,\n\t\tRange:       ca.Range,\n\t}\n}\n\n// noshade={ templ.Bool(...) }\ntype BoolExpressionAttribute struct {\n\tKey        AttributeKey\n\tExpression Expression\n\tRange      Range\n}\n\nfunc (bea *BoolExpressionAttribute) String() string {\n\treturn bea.Key.String() + `?={ ` + bea.Expression.Value + ` }`\n}\n\nfunc (bea *BoolExpressionAttribute) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, bea.String())\n}\n\nfunc (bea *BoolExpressionAttribute) Visit(v Visitor) error {\n\treturn v.VisitBoolExpressionAttribute(bea)\n}\n\nfunc (bea *BoolExpressionAttribute) Copy() Attribute {\n\treturn &BoolExpressionAttribute{\n\t\tExpression: bea.Expression,\n\t\tKey:        bea.Key,\n\t\tRange:      bea.Range,\n\t}\n}\n\n// href={ ... }\ntype ExpressionAttribute struct {\n\tKey        AttributeKey\n\tExpression Expression\n}\n\nfunc (ea *ExpressionAttribute) String() string {\n\tsb := new(strings.Builder)\n\t_ = ea.Write(sb, 0)\n\treturn sb.String()\n}\n\nfunc (ea *ExpressionAttribute) formatExpression() (exp []string) {\n\ttrimmed := strings.TrimSpace(ea.Expression.Value)\n\tif !strings.Contains(trimmed, \"\\n\") {\n\t\tformatted, err := format.Source([]byte(trimmed))\n\t\tif err != nil {\n\t\t\treturn []string{trimmed}\n\t\t}\n\t\treturn []string{string(formatted)}\n\t}\n\n\tbuf := bytes.NewBufferString(\"[]any{\\n\")\n\tbuf.WriteString(trimmed)\n\tbuf.WriteString(\"\\n}\")\n\n\tformatted, err := format.Source(buf.Bytes())\n\tif err != nil {\n\t\treturn []string{trimmed}\n\t}\n\n\t// Trim prefix and suffix.\n\tlines := strings.Split(string(formatted), \"\\n\")\n\tif len(lines) < 3 {\n\t\treturn []string{trimmed}\n\t}\n\n\t// Return.\n\treturn lines[1 : len(lines)-1]\n}\n\nfunc (ea *ExpressionAttribute) Write(w io.Writer, indent int) (err error) {\n\tlines := ea.formatExpression()\n\tif len(lines) == 1 {\n\t\treturn writeIndent(w, indent, ea.Key.String(), `={ `, lines[0], ` }`)\n\t}\n\n\tif err = writeIndent(w, indent, ea.Key.String(), \"={\\n\"); err != nil {\n\t\treturn err\n\t}\n\tfor _, line := range lines {\n\t\tif err = writeIndent(w, indent, line, \"\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn writeIndent(w, indent, \"}\")\n}\n\nfunc (ea *ExpressionAttribute) Visit(v Visitor) error {\n\treturn v.VisitExpressionAttribute(ea)\n}\n\nfunc (ea *ExpressionAttribute) Copy() Attribute {\n\treturn &ExpressionAttribute{\n\t\tExpression: ea.Expression,\n\t\tKey:        ea.Key,\n\t}\n}\n\n// <a { spread... } />\ntype SpreadAttributes struct {\n\tExpression Expression\n\tRange      Range\n}\n\nfunc (sa *SpreadAttributes) String() string {\n\treturn `{ ` + sa.Expression.Value + `... }`\n}\n\nfunc (sa *SpreadAttributes) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, sa.String())\n}\n\nfunc (sa *SpreadAttributes) Visit(v Visitor) error {\n\treturn v.VisitSpreadAttributes(sa)\n}\n\nfunc (sa *SpreadAttributes) Copy() Attribute {\n\treturn &SpreadAttributes{\n\t\tExpression: sa.Expression,\n\t\tRange:      sa.Range,\n\t}\n}\n\n//\t<a href=\"test\" \\\n//\t\tif active {\n//\t   class=\"isActive\"\n//\t }\ntype ConditionalAttribute struct {\n\tExpression Expression\n\tThen       []Attribute\n\tElse       []Attribute\n\tRange      Range\n}\n\nfunc (ca *ConditionalAttribute) String() string {\n\tsb := new(strings.Builder)\n\t_ = ca.Write(sb, 0)\n\treturn sb.String()\n}\n\nfunc (ca *ConditionalAttribute) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, \"if \"); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.Write([]byte(ca.Expression.Value)); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.Write([]byte(\" {\\n\")); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindent++\n\t\tfor _, attr := range ca.Then {\n\t\t\tif err := attr.Write(w, indent); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif _, err := w.Write([]byte(\"\\n\")); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tindent--\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\tif len(ca.Else) == 0 {\n\t\treturn nil\n\t}\n\t// Write the else blocks.\n\tif _, err := w.Write([]byte(\" else {\\n\")); err != nil {\n\t\treturn err\n\t}\n\t{\n\t\tindent++\n\t\tfor _, attr := range ca.Else {\n\t\t\tif err := attr.Write(w, indent); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif _, err := w.Write([]byte(\"\\n\")); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tindent--\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (ca *ConditionalAttribute) Visit(v Visitor) error {\n\treturn v.VisitConditionalAttribute(ca)\n}\n\nfunc (ca *ConditionalAttribute) Copy() Attribute {\n\treturn &ConditionalAttribute{\n\t\tExpression: ca.Expression,\n\t\tThen:       CopyAttributes(ca.Then),\n\t\tElse:       CopyAttributes(ca.Else),\n\t\tRange:      ca.Range,\n\t}\n}\n\nfunc CopyAttributes(attrs []Attribute) (copies []Attribute) {\n\tcopies = make([]Attribute, len(attrs))\n\tfor i, a := range attrs {\n\t\tcopies[i] = a.Copy()\n\t}\n\treturn copies\n}\n\n// GoComment.\ntype GoComment struct {\n\tContents  string\n\tMultiline bool\n\tRange     Range\n}\n\nfunc (c *GoComment) IsNode() bool { return true }\nfunc (c *GoComment) Write(w io.Writer, indent int) error {\n\tif c.Multiline {\n\t\treturn writeIndent(w, indent, \"/*\", c.Contents, \"*/\")\n\t}\n\treturn writeIndent(w, indent, \"//\", c.Contents)\n}\n\nfunc (c *GoComment) Visit(v Visitor) error {\n\treturn v.VisitGoComment(c)\n}\n\n// HTMLComment.\ntype HTMLComment struct {\n\tContents string\n\tRange    Range\n}\n\nfunc (c *HTMLComment) IsNode() bool { return true }\nfunc (c *HTMLComment) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, \"<!--\", c.Contents, \"-->\")\n}\n\nfunc (c *HTMLComment) Visit(v Visitor) error {\n\treturn v.VisitHTMLComment(c)\n}\n\ntype Fallthrough struct {\n\tRange Range\n}\n\nfunc (f *Fallthrough) IsNode() bool { return true }\nfunc (f *Fallthrough) Write(w io.Writer, indent int) error {\n\treturn writeIndent(w, indent, \"fallthrough\")\n}\n\nfunc (f *Fallthrough) Visit(v Visitor) error {\n\treturn v.VisitFallthrough(f)\n}\n\n// Nodes.\n\n// CallTemplateExpression can be used to create and render a template using data.\n// {! Other(p.First, p.Last) }\n// or it can be used to render a template parameter.\n// {! v }\ntype CallTemplateExpression struct {\n\t// Expression returns a template to execute.\n\tExpression Expression\n\tRange      Range\n}\n\nfunc (cte *CallTemplateExpression) IsNode() bool { return true }\nfunc (cte *CallTemplateExpression) Write(w io.Writer, indent int) error {\n\t// Rewrite to new call syntax\n\treturn writeIndent(w, indent, `@`, cte.Expression.Value)\n}\n\nfunc (cte *CallTemplateExpression) Visit(v Visitor) error {\n\treturn v.VisitCallTemplateExpression(cte)\n}\n\n// TemplElementExpression can be used to create and render a template using data.\n// @Other(p.First, p.Last)\n// or it can be used to render a template parameter.\n// @v\ntype TemplElementExpression struct {\n\t// Expression returns a template to execute.\n\tExpression Expression\n\t// Children returns the elements in a block element.\n\tChildren []Node\n\tRange    Range\n}\n\nfunc (tee TemplElementExpression) ChildNodes() []Node {\n\treturn tee.Children\n}\nfunc (tee *TemplElementExpression) IsNode() bool { return true }\nfunc (tee *TemplElementExpression) Write(w io.Writer, indent int) error {\n\tsource, err := format.Source([]byte(tee.Expression.Value))\n\tif err != nil {\n\t\tsource = []byte(tee.Expression.Value)\n\t}\n\t// Indent all lines and re-format, we can then use this to only re-indent lines that gofmt would modify.\n\treformattedSource, err := format.Source(bytes.ReplaceAll(source, []byte(\"\\n\"), []byte(\"\\n\\t\")))\n\tif err != nil {\n\t\treformattedSource = source\n\t}\n\tsourceLines := bytes.Split(source, []byte(\"\\n\"))\n\treformattedSourceLines := bytes.Split(reformattedSource, []byte(\"\\n\"))\n\tfor i := range sourceLines {\n\t\tif i == 0 {\n\t\t\tif err := writeIndent(w, indent, \"@\"+string(sourceLines[i])); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif _, err := io.WriteString(w, \"\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Blank lines should not have any indentation.\n\t\tif len(bytes.TrimSpace(sourceLines[i])) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif string(sourceLines[i]) != string(reformattedSourceLines[i]) {\n\t\t\tif _, err := w.Write(sourceLines[i]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif err := writeIndent(w, indent, string(sourceLines[i])); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif len(tee.Children) == 0 {\n\t\treturn nil\n\t}\n\tif _, err = io.WriteString(w, \" {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err := writeNodesIndented(w, indent+1, tee.Children); err != nil {\n\t\treturn err\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (tee *TemplElementExpression) Visit(v Visitor) error {\n\treturn v.VisitTemplElementExpression(tee)\n}\n\n// ChildrenExpression can be used to render the children of a templ element.\n// { children ... }\ntype ChildrenExpression struct {\n\tRange Range\n}\n\nfunc (*ChildrenExpression) IsNode() bool { return true }\nfunc (*ChildrenExpression) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, \"{ children... }\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (ce *ChildrenExpression) Visit(v Visitor) error {\n\treturn v.VisitChildrenExpression(ce)\n}\n\n// if p.Type == \"test\" && p.thing {\n// }\ntype IfExpression struct {\n\tExpression Expression\n\tThen       []Node\n\tElseIfs    []ElseIfExpression\n\tElse       []Node\n\tRange      Range\n}\n\ntype ElseIfExpression struct {\n\tExpression Expression\n\tThen       []Node\n\tRange      Range\n}\n\nfunc (n IfExpression) ChildNodes() []Node {\n\tvar nodes []Node\n\tnodes = append(nodes, n.Then...)\n\tnodes = append(nodes, n.Else...)\n\tfor _, elseIf := range n.ElseIfs {\n\t\tnodes = append(nodes, elseIf.Then...)\n\t}\n\treturn nodes\n}\nfunc (n *IfExpression) IsNode() bool { return true }\nfunc (n *IfExpression) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, \"if \", n.Expression.Value, \" {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindent++\n\tif err := writeNodesIndented(w, indent, n.Then); err != nil {\n\t\treturn err\n\t}\n\tindent--\n\tfor _, elseIf := range n.ElseIfs {\n\t\tif err := writeIndent(w, indent, \"} else if \", elseIf.Expression.Value, \" {\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindent++\n\t\tif err := writeNodesIndented(w, indent, elseIf.Then); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tindent--\n\t}\n\tif len(n.Else) > 0 {\n\t\tif err := writeIndent(w, indent, \"} else {\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := writeNodesIndented(w, indent+1, n.Else); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (n *IfExpression) Visit(v Visitor) error {\n\treturn v.VisitIfExpression(n)\n}\n\n//\tswitch p.Type {\n//\t case \"Something\":\n//\t}\ntype SwitchExpression struct {\n\tExpression Expression\n\tCases      []CaseExpression\n\tRange      Range\n}\n\nfunc (se SwitchExpression) ChildNodes() []Node {\n\tvar nodes []Node\n\tfor _, c := range se.Cases {\n\t\tnodes = append(nodes, c.Children...)\n\t}\n\treturn nodes\n}\nfunc (se *SwitchExpression) IsNode() bool { return true }\nfunc (se *SwitchExpression) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, \"switch \", se.Expression.Value, \" {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tindent++\n\tfor _, c := range se.Cases {\n\t\tif err := writeIndent(w, indent, c.Expression.Value, \"\\n\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := writeNodesIndented(w, indent+1, c.Children); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tindent--\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (se *SwitchExpression) Visit(v Visitor) error {\n\treturn v.VisitSwitchExpression(se)\n}\n\n// case \"Something\":\ntype CaseExpression struct {\n\tExpression Expression\n\tChildren   []Node\n}\n\n//\tfor i, v := range p.Addresses {\n//\t  {! Address(v) }\n//\t}\ntype ForExpression struct {\n\tExpression Expression\n\tChildren   []Node\n\tRange      Range\n}\n\nfunc (fe ForExpression) ChildNodes() []Node {\n\treturn fe.Children\n}\nfunc (fe *ForExpression) IsNode() bool { return true }\nfunc (fe *ForExpression) Write(w io.Writer, indent int) error {\n\tif err := writeIndent(w, indent, \"for \", fe.Expression.Value, \" {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif err := writeNodesIndented(w, indent+1, fe.Children); err != nil {\n\t\treturn err\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (fe *ForExpression) Visit(v Visitor) error {\n\treturn v.VisitForExpression(fe)\n}\n\n// GoCode is used within HTML elements, and allows arbitrary go code.\n// {{ ... }}\ntype GoCode struct {\n\tExpression Expression\n\t// TrailingSpace lists what happens after the expression.\n\tTrailingSpace TrailingSpace\n\tMultiline     bool\n}\n\nfunc (gc *GoCode) Trailing() TrailingSpace {\n\treturn gc.TrailingSpace\n}\n\nfunc (gc *GoCode) IsNode() bool { return true }\nfunc (gc *GoCode) Write(w io.Writer, indent int) error {\n\tif isWhitespace(gc.Expression.Value) {\n\t\tgc.Expression.Value = \"\"\n\t}\n\tif !gc.Multiline {\n\t\tsource, err := format.Source([]byte(gc.Expression.Value))\n\t\tif err != nil {\n\t\t\tsource = []byte(gc.Expression.Value)\n\t\t}\n\t\treturn writeIndent(w, indent, `{{ `, string(source), ` }}`)\n\t}\n\tsource, err := format.Source([]byte(strings.Repeat(\"\\t\", indent+1) + gc.Expression.Value))\n\tif err != nil {\n\t\tsource = []byte(gc.Expression.Value)\n\t}\n\tif err := writeIndent(w, indent, \"{{\\n\"+string(source)+\"\\n\"); err != nil {\n\t\treturn err\n\t}\n\treturn writeIndent(w, indent, \"}}\")\n}\n\nfunc (gc *GoCode) Visit(v Visitor) error {\n\treturn v.VisitGoCode(gc)\n}\n\n// StringExpression is used within HTML elements, and for style values.\n// { ... }\ntype StringExpression struct {\n\tExpression Expression\n\t// TrailingSpace lists what happens after the expression.\n\tTrailingSpace TrailingSpace\n}\n\nfunc (se *StringExpression) Trailing() TrailingSpace {\n\treturn se.TrailingSpace\n}\n\nfunc (se *StringExpression) IsNode() bool                  { return true }\nfunc (se *StringExpression) IsStyleDeclarationValue() bool { return true }\nfunc (se *StringExpression) Write(w io.Writer, indent int) error {\n\tif isWhitespace(se.Expression.Value) {\n\t\tse.Expression.Value = \"\"\n\t}\n\treturn writeIndent(w, indent, `{ `, se.Expression.Value, ` }`)\n}\n\nfunc (se *StringExpression) Visit(v Visitor) error {\n\treturn v.VisitStringExpression(se)\n}\n\n// ScriptTemplate is a script block.\ntype ScriptTemplate struct {\n\tRange      Range\n\tName       Expression\n\tParameters Expression\n\tValue      string\n}\n\nfunc (s *ScriptTemplate) IsTemplateFileNode() bool { return true }\nfunc (s *ScriptTemplate) Write(w io.Writer, indent int) error {\n\tsource := formatFunctionArguments(s.Name.Value + \"(\" + s.Parameters.Value + \")\")\n\tif err := writeIndent(w, indent, \"script \", string(source), \" {\\n\"); err != nil {\n\t\treturn err\n\t}\n\tif _, err := io.WriteString(w, s.Value); err != nil {\n\t\treturn err\n\t}\n\tif err := writeIndent(w, indent, \"}\"); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (s *ScriptTemplate) Visit(v Visitor) error {\n\treturn v.VisitScriptTemplate(s)\n}\n\n// formatFunctionArguments formats the function arguments, if possible.\nfunc formatFunctionArguments(expression string) string {\n\tsource := []byte(expression)\n\tformatted, err := format.Source([]byte(\"func \" + expression))\n\tif err == nil {\n\t\tformatted = bytes.TrimPrefix(formatted, []byte(\"func \"))\n\t\tsource = formatted\n\t}\n\treturn string(source)\n}\n"
  },
  {
    "path": "parser/v2/visitor/visitor.go",
    "content": "package visitor\n\nimport \"github.com/a-h/templ/parser/v2\"\n\n// New returns a default Visitor. Each function in the Visitor struct can be\n// overridden to provide custom behavior when visiting nodes in the parse tree.\nfunc New() *Visitor {\n\tv := &Visitor{}\n\n\t// Set default implementations for all visitor functions.\n\tv.TemplateFile = func(n *parser.TemplateFile) error {\n\t\tfor _, header := range n.Header {\n\t\t\tif err := v.VisitTemplateFileGoExpression(header); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err := v.VisitPackage(&n.Package); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, node := range n.Nodes {\n\t\t\tif err := node.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.TemplateFileGoExpression = func(n *parser.TemplateFileGoExpression) error {\n\t\treturn nil\n\t}\n\tv.Package = func(n *parser.Package) error {\n\t\treturn nil\n\t}\n\tv.Whitespace = func(n *parser.Whitespace) error {\n\t\treturn nil\n\t}\n\tv.CSSTemplate = func(n *parser.CSSTemplate) error {\n\t\tfor _, prop := range n.Properties {\n\t\t\tif err := prop.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.ConstantCSSProperty = func(n *parser.ConstantCSSProperty) error {\n\t\treturn nil\n\t}\n\tv.ExpressionCSSProperty = func(n *parser.ExpressionCSSProperty) error {\n\t\tif err := n.Value.Visit(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\tv.DocType = func(n *parser.DocType) error {\n\t\treturn nil\n\t}\n\tv.HTMLTemplate = func(n *parser.HTMLTemplate) error {\n\t\tfor _, child := range n.Children {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.Text = func(n *parser.Text) error {\n\t\treturn nil\n\t}\n\tv.Element = func(n *parser.Element) error {\n\t\tfor _, attr := range n.Attributes {\n\t\t\tif err := attr.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tfor _, child := range n.Children {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.RawElement = func(n *parser.RawElement) error {\n\t\tfor _, attr := range n.Attributes {\n\t\t\tif err := attr.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.ScriptElement = func(n *parser.ScriptElement) error {\n\t\tfor _, attr := range n.Attributes {\n\t\t\tif err := attr.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.BoolConstantAttribute = func(n *parser.BoolConstantAttribute) error {\n\t\treturn nil\n\t}\n\tv.ConstantAttribute = func(n *parser.ConstantAttribute) error {\n\t\treturn nil\n\t}\n\tv.BoolExpressionAttribute = func(n *parser.BoolExpressionAttribute) error {\n\t\treturn nil\n\t}\n\tv.ExpressionAttribute = func(n *parser.ExpressionAttribute) error {\n\t\treturn nil\n\t}\n\tv.SpreadAttributes = func(n *parser.SpreadAttributes) error {\n\t\treturn nil\n\t}\n\tv.ConditionalAttribute = func(n *parser.ConditionalAttribute) error {\n\t\tfor _, child := range n.Then {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tfor _, child := range n.Else {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.GoComment = func(n *parser.GoComment) error {\n\t\treturn nil\n\t}\n\tv.HTMLComment = func(n *parser.HTMLComment) error {\n\t\treturn nil\n\t}\n\tv.CallTemplateExpression = func(n *parser.CallTemplateExpression) error {\n\t\treturn nil\n\t}\n\tv.TemplElementExpression = func(n *parser.TemplElementExpression) error {\n\t\tfor _, child := range n.Children {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.ChildrenExpression = func(n *parser.ChildrenExpression) error {\n\t\treturn nil\n\t}\n\tv.IfExpression = func(n *parser.IfExpression) error {\n\t\tfor _, child := range n.Then {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tfor _, child := range n.ElseIfs {\n\t\t\tfor _, child := range child.Then {\n\t\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor _, child := range n.Else {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.SwitchExpression = func(n *parser.SwitchExpression) error {\n\t\tfor _, node := range n.Cases {\n\t\t\tfor _, child := range node.Children {\n\t\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.ForExpression = func(n *parser.ForExpression) error {\n\t\tfor _, child := range n.Children {\n\t\t\tif err := child.Visit(v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tv.GoCode = func(n *parser.GoCode) error {\n\t\treturn nil\n\t}\n\tv.StringExpression = func(n *parser.StringExpression) error {\n\t\treturn nil\n\t}\n\tv.ScriptTemplate = func(n *parser.ScriptTemplate) error {\n\t\treturn nil\n\t}\n\tv.Fallthrough = func(n *parser.Fallthrough) error {\n\t\treturn nil\n\t}\n\n\treturn v\n}\n\n// Visitor implements the parser.Visitor interface. Each function corresponds to a node type in the parse tree.\n// Override these functions to provide custom behavior when visiting nodes.\ntype Visitor struct {\n\tTemplateFile             func(n *parser.TemplateFile) error\n\tTemplateFileGoExpression func(n *parser.TemplateFileGoExpression) error\n\tPackage                  func(n *parser.Package) error\n\tWhitespace               func(n *parser.Whitespace) error\n\tCSSTemplate              func(n *parser.CSSTemplate) error\n\tConstantCSSProperty      func(n *parser.ConstantCSSProperty) error\n\tExpressionCSSProperty    func(n *parser.ExpressionCSSProperty) error\n\tDocType                  func(n *parser.DocType) error\n\tHTMLTemplate             func(n *parser.HTMLTemplate) error\n\tText                     func(n *parser.Text) error\n\tElement                  func(n *parser.Element) error\n\tRawElement               func(n *parser.RawElement) error\n\tScriptElement            func(n *parser.ScriptElement) error\n\tBoolConstantAttribute    func(n *parser.BoolConstantAttribute) error\n\tConstantAttribute        func(n *parser.ConstantAttribute) error\n\tBoolExpressionAttribute  func(n *parser.BoolExpressionAttribute) error\n\tExpressionAttribute      func(n *parser.ExpressionAttribute) error\n\tSpreadAttributes         func(n *parser.SpreadAttributes) error\n\tConditionalAttribute     func(n *parser.ConditionalAttribute) error\n\tGoComment                func(n *parser.GoComment) error\n\tHTMLComment              func(n *parser.HTMLComment) error\n\tCallTemplateExpression   func(n *parser.CallTemplateExpression) error\n\tTemplElementExpression   func(n *parser.TemplElementExpression) error\n\tChildrenExpression       func(n *parser.ChildrenExpression) error\n\tIfExpression             func(n *parser.IfExpression) error\n\tSwitchExpression         func(n *parser.SwitchExpression) error\n\tForExpression            func(n *parser.ForExpression) error\n\tGoCode                   func(n *parser.GoCode) error\n\tStringExpression         func(n *parser.StringExpression) error\n\tScriptTemplate           func(n *parser.ScriptTemplate) error\n\tFallthrough              func(n *parser.Fallthrough) error\n}\n\nvar _ parser.Visitor = (*Visitor)(nil)\n\nfunc (v *Visitor) VisitTemplateFile(n *parser.TemplateFile) error {\n\treturn v.TemplateFile(n)\n}\n\nfunc (v *Visitor) VisitTemplateFileGoExpression(n *parser.TemplateFileGoExpression) error {\n\treturn v.TemplateFileGoExpression(n)\n}\n\nfunc (v *Visitor) VisitPackage(n *parser.Package) error {\n\treturn v.Package(n)\n}\n\nfunc (v *Visitor) VisitWhitespace(n *parser.Whitespace) error {\n\treturn v.Whitespace(n)\n}\n\nfunc (v *Visitor) VisitCSSTemplate(n *parser.CSSTemplate) error {\n\treturn v.CSSTemplate(n)\n}\nfunc (v *Visitor) VisitConstantCSSProperty(n *parser.ConstantCSSProperty) error {\n\treturn v.ConstantCSSProperty(n)\n}\n\nfunc (v *Visitor) VisitExpressionCSSProperty(n *parser.ExpressionCSSProperty) error {\n\treturn v.ExpressionCSSProperty(n)\n}\n\nfunc (v *Visitor) VisitDocType(n *parser.DocType) error {\n\treturn v.DocType(n)\n}\n\nfunc (v *Visitor) VisitHTMLTemplate(n *parser.HTMLTemplate) error {\n\treturn v.HTMLTemplate(n)\n}\n\nfunc (v *Visitor) VisitText(n *parser.Text) error {\n\treturn v.Text(n)\n}\n\nfunc (v *Visitor) VisitElement(n *parser.Element) error {\n\treturn v.Element(n)\n}\n\nfunc (v *Visitor) VisitRawElement(n *parser.RawElement) error {\n\treturn v.RawElement(n)\n}\n\nfunc (v *Visitor) VisitScriptElement(n *parser.ScriptElement) error {\n\treturn v.ScriptElement(n)\n}\n\nfunc (v *Visitor) VisitBoolConstantAttribute(n *parser.BoolConstantAttribute) error {\n\treturn v.BoolConstantAttribute(n)\n}\n\nfunc (v *Visitor) VisitConstantAttribute(n *parser.ConstantAttribute) error {\n\treturn v.ConstantAttribute(n)\n}\n\nfunc (v *Visitor) VisitBoolExpressionAttribute(n *parser.BoolExpressionAttribute) error {\n\treturn v.BoolExpressionAttribute(n)\n}\n\nfunc (v *Visitor) VisitExpressionAttribute(n *parser.ExpressionAttribute) error {\n\treturn v.ExpressionAttribute(n)\n}\n\nfunc (v *Visitor) VisitSpreadAttributes(n *parser.SpreadAttributes) error {\n\treturn v.SpreadAttributes(n)\n}\n\nfunc (v *Visitor) VisitConditionalAttribute(n *parser.ConditionalAttribute) error {\n\treturn v.ConditionalAttribute(n)\n}\n\nfunc (v *Visitor) VisitGoComment(n *parser.GoComment) error {\n\treturn v.GoComment(n)\n}\n\nfunc (v *Visitor) VisitHTMLComment(n *parser.HTMLComment) error {\n\treturn v.HTMLComment(n)\n}\n\nfunc (v *Visitor) VisitCallTemplateExpression(n *parser.CallTemplateExpression) error {\n\treturn v.CallTemplateExpression(n)\n}\n\nfunc (v *Visitor) VisitTemplElementExpression(n *parser.TemplElementExpression) error {\n\treturn v.TemplElementExpression(n)\n}\n\nfunc (v *Visitor) VisitChildrenExpression(n *parser.ChildrenExpression) error {\n\treturn v.ChildrenExpression(n)\n}\n\nfunc (v *Visitor) VisitIfExpression(n *parser.IfExpression) error {\n\treturn v.IfExpression(n)\n}\n\nfunc (v *Visitor) VisitSwitchExpression(n *parser.SwitchExpression) error {\n\treturn v.SwitchExpression(n)\n}\n\nfunc (v *Visitor) VisitForExpression(n *parser.ForExpression) error {\n\treturn v.ForExpression(n)\n}\n\nfunc (v *Visitor) VisitGoCode(n *parser.GoCode) error {\n\treturn v.GoCode(n)\n}\n\nfunc (v *Visitor) VisitStringExpression(n *parser.StringExpression) error {\n\treturn v.StringExpression(n)\n}\n\nfunc (v *Visitor) VisitScriptTemplate(n *parser.ScriptTemplate) error {\n\treturn v.ScriptTemplate(n)\n}\n\nfunc (v *Visitor) VisitFallthrough(n *parser.Fallthrough) error {\n\treturn v.Fallthrough(n)\n}\n"
  },
  {
    "path": "parser/v2/visitor/visitor_test.go",
    "content": "package visitor_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ/parser/v2\"\n\t\"github.com/a-h/templ/parser/v2/visitor\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc assetRewriter(rewrite func(path string) string) parser.Visitor {\n\tar := visitor.New()\n\tinSrcElement := false\n\tinHrefElement := false\n\n\t// Save the original Element visitor to allow chaining.\n\tvisitElement := ar.Element\n\tar.Element = func(e *parser.Element) error {\n\t\tswitch e.Name {\n\t\tcase \"link\":\n\t\t\tinHrefElement = true\n\t\tcase \"img\":\n\t\t\tinSrcElement = true\n\t\t}\n\t\t// Visit child elements.\n\t\tif err := visitElement(e); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tinHrefElement = false\n\t\tinSrcElement = false\n\t\treturn nil\n\t}\n\n\t// Save the original ScriptElement visitor to allow chaining.\n\tvisitScriptElement := ar.ScriptElement\n\tar.ScriptElement = func(e *parser.ScriptElement) error {\n\t\tinSrcElement = true\n\t\t// Visit child script elements.\n\t\tif err := visitScriptElement(e); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tinSrcElement = false\n\t\treturn nil\n\t}\n\n\t// Save the original ConstantAttribute visitor to allow chaining.\n\tvisitConstantAttribute := ar.ConstantAttribute\n\tar.ConstantAttribute = func(n *parser.ConstantAttribute) error {\n\t\tif inSrcElement && n.Key.String() == \"src\" {\n\t\t\tn.Value = rewrite(n.Value)\n\t\t}\n\t\tif inHrefElement && n.Key.String() == \"href\" {\n\t\t\tn.Value = rewrite(n.Value)\n\t\t}\n\t\treturn visitConstantAttribute(n)\n\t}\n\n\treturn ar\n}\n\nfunc TestVisitorAssetRewriter(t *testing.T) {\n\tinput := `package view\n\ntempl indexStyles() {\n\t<link rel=\"stylesheet\" href=\"view/index.css\"/>\n}\n\ntempl indexScripts() {\n\t<script src=\"view/index.js\" type=\"module\" defer></script>\n}\n\ntempl Index(title string, res *hn.SearchResponse) {\n\t@layout(&Layout{\n\t\tStyles:  indexStyles,\n\t\tScripts: indexScripts,\n\t}) {\n\t\t@index(res)\n\t}\n}\n\ntempl index(res *hn.SearchResponse) {\n\t<main class=\"index\">\n\t\t@Header()\n\t\tfor _, story := range res.Stories {\n\t\t\t@storyComponent(story)\n\t\t}\n\t\t@Pagination(res.Page, res.NumPages)\n\t</main>\n}\n`\n\ttemplateFile, err := parser.ParseString(input)\n\tif err != nil {\n\t\tt.Fatalf(\"parser error: %v\", err)\n\t}\n\trewriter := assetRewriter(func(assetPath string) string {\n\t\treturn \"http://somecdn.com/\" + assetPath\n\t})\n\tif err := templateFile.Visit(rewriter); err != nil {\n\t\tt.Fatalf(\"error visiting template file: %v\", err)\n\t}\n\n\tvar actual bytes.Buffer\n\tif err := templateFile.Write(&actual); err != nil {\n\t\tt.Fatalf(\"error writing template file: %v\", err)\n\t}\n\texpected := `package view\n\ntempl indexStyles() {\n\t<link rel=\"stylesheet\" href=\"http://somecdn.com/view/index.css\"/>\n}\n\ntempl indexScripts() {\n\t<script src=\"http://somecdn.com/view/index.js\" type=\"module\" defer></script>\n}\n\ntempl Index(title string, res *hn.SearchResponse) {\n\t@layout(&Layout{\n\t\tStyles:  indexStyles,\n\t\tScripts: indexScripts,\n\t}) {\n\t\t@index(res)\n\t}\n}\n\ntempl index(res *hn.SearchResponse) {\n\t<main class=\"index\">\n\t\t@Header()\n\t\tfor _, story := range res.Stories {\n\t\t\t@storyComponent(story)\n\t\t}\n\t\t@Pagination(res.Page, res.NumPages)\n\t</main>\n}\n`\n\tif diff := cmp.Diff(expected, actual.String()); diff != \"\" {\n\t\tt.Fatalf(\"expected != actual:\\n%s\", diff)\n\t}\n}\n"
  },
  {
    "path": "parser/v2/visitor.go",
    "content": "package parser\n\n// Visitor is an interface for visiting nodes in the parse tree.\ntype Visitor interface {\n\tVisitTemplateFile(*TemplateFile) error\n\tVisitTemplateFileGoExpression(*TemplateFileGoExpression) error\n\tVisitPackage(*Package) error\n\tVisitWhitespace(*Whitespace) error\n\tVisitCSSTemplate(*CSSTemplate) error\n\tVisitConstantCSSProperty(*ConstantCSSProperty) error\n\tVisitExpressionCSSProperty(*ExpressionCSSProperty) error\n\tVisitDocType(*DocType) error\n\tVisitHTMLTemplate(*HTMLTemplate) error\n\tVisitText(*Text) error\n\tVisitElement(*Element) error\n\tVisitScriptElement(*ScriptElement) error\n\tVisitRawElement(*RawElement) error\n\tVisitBoolConstantAttribute(*BoolConstantAttribute) error\n\tVisitConstantAttribute(*ConstantAttribute) error\n\tVisitBoolExpressionAttribute(*BoolExpressionAttribute) error\n\tVisitExpressionAttribute(*ExpressionAttribute) error\n\tVisitSpreadAttributes(*SpreadAttributes) error\n\tVisitConditionalAttribute(*ConditionalAttribute) error\n\tVisitGoComment(*GoComment) error\n\tVisitHTMLComment(*HTMLComment) error\n\tVisitCallTemplateExpression(*CallTemplateExpression) error\n\tVisitTemplElementExpression(*TemplElementExpression) error\n\tVisitChildrenExpression(*ChildrenExpression) error\n\tVisitIfExpression(*IfExpression) error\n\tVisitSwitchExpression(*SwitchExpression) error\n\tVisitForExpression(*ForExpression) error\n\tVisitGoCode(*GoCode) error\n\tVisitStringExpression(*StringExpression) error\n\tVisitScriptTemplate(*ScriptTemplate) error\n\tVisitFallthrough(*Fallthrough) error\n}\n"
  },
  {
    "path": "parser/v2/whitespaceparser.go",
    "content": "package parser\n\nimport \"github.com/a-h/parse\"\n\n// Eat any whitespace.\nvar whitespaceExpression = parse.Func(func(pi *parse.Input) (n Node, ok bool, err error) {\n\tr := &Whitespace{}\n\tstart := pi.Position()\n\tif r.Value, ok, err = parse.OptionalWhitespace.Parse(pi); err != nil || !ok {\n\t\treturn\n\t}\n\tr.Range = NewRange(start, pi.Position())\n\treturn r, len(r.Value) > 0, nil\n})\n"
  },
  {
    "path": "runtime/buffer.go",
    "content": "package runtime\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"net/http\"\n)\n\n// DefaultBufferSize is the default size of buffers. It is set to 4KB by default, which is the\n// same as the default buffer size of bufio.Writer.\nvar DefaultBufferSize = 4 * 1024 // 4KB\n\n// Buffer is a wrapper around bufio.Writer that enables flushing and closing of\n// the underlying writer.\ntype Buffer struct {\n\tUnderlying io.Writer\n\tb          *bufio.Writer\n}\n\n// Write the contents of p into the buffer.\nfunc (b *Buffer) Write(p []byte) (n int, err error) {\n\treturn b.b.Write(p)\n}\n\n// Flush writes any buffered data to the underlying io.Writer and\n// calls the Flush method of the underlying http.Flusher if it implements it.\nfunc (b *Buffer) Flush() error {\n\tif err := b.b.Flush(); err != nil {\n\t\treturn err\n\t}\n\tif f, ok := b.Underlying.(http.Flusher); ok {\n\t\tf.Flush()\n\t}\n\treturn nil\n}\n\n// Close closes the buffer and the underlying io.Writer if it implements io.Closer.\nfunc (b *Buffer) Close() error {\n\tif c, ok := b.Underlying.(io.Closer); ok {\n\t\treturn c.Close()\n\t}\n\treturn nil\n}\n\n// Reset sets the underlying io.Writer to w and resets the buffer.\nfunc (b *Buffer) Reset(w io.Writer) {\n\tif b.b == nil {\n\t\tb.b = bufio.NewWriterSize(b, DefaultBufferSize)\n\t}\n\tb.Underlying = w\n\tb.b.Reset(w)\n}\n\n// Size returns the size of the underlying buffer in bytes.\nfunc (b *Buffer) Size() int {\n\treturn b.b.Size()\n}\n\n// WriteString writes the contents of s into the buffer.\nfunc (b *Buffer) WriteString(s string) (n int, err error) {\n\treturn b.b.WriteString(s)\n}\n"
  },
  {
    "path": "runtime/buffer_test.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"net/http/httptest\"\n\t\"testing\"\n)\n\nvar wasClosed bool\n\ntype closable struct {\n\t*httptest.ResponseRecorder\n}\n\nfunc (c *closable) Close() error {\n\twasClosed = true\n\treturn nil\n}\n\nfunc TestBuffer(t *testing.T) {\n\tunderlying := httptest.NewRecorder()\n\tw, _ := GetBuffer(&closable{underlying})\n\tt.Run(\"can write to a buffer\", func(t *testing.T) {\n\t\tif _, err := w.Write([]byte(\"A\")); err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"can write a string to a buffer\", func(t *testing.T) {\n\t\tif _, err := w.WriteString(\"A\"); err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"can flush a buffer\", func(t *testing.T) {\n\t\tif err := w.Flush(); err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"can close a buffer\", func(t *testing.T) {\n\t\tif err := w.Close(); err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t\tif !wasClosed {\n\t\t\tt.Error(\"expected the underlying writer to be closed\")\n\t\t}\n\t})\n\tt.Run(\"can get the size of a buffer\", func(t *testing.T) {\n\t\tif w.Size() != DefaultBufferSize {\n\t\t\tt.Errorf(\"expected %d, got %d\", DefaultBufferSize, w.Size())\n\t\t}\n\t})\n\tt.Run(\"can reset a buffer\", func(t *testing.T) {\n\t\tw.Reset(underlying)\n\t})\n\tif underlying.Body.String() != \"AA\" {\n\t\tt.Errorf(\"expected %q, got %q\", \"AA\", underlying.Body.String())\n\t}\n}\n\ntype failStream struct {\n}\n\nvar errTest = errors.New(\"test error\")\n\nfunc (f *failStream) Write(p []byte) (n int, err error) {\n\treturn 0, errTest\n}\n\nfunc (f *failStream) Close() error {\n\treturn errTest\n}\n\nfunc TestBufferErrors(t *testing.T) {\n\tw, _ := GetBuffer(&failStream{})\n\tt.Run(\"close errors are returned\", func(t *testing.T) {\n\t\tif err := w.Close(); err != errTest {\n\t\t\tt.Errorf(\"expected %v, got %v\", errTest, err)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "runtime/bufferpool.go",
    "content": "package runtime\n\nimport (\n\t\"io\"\n\t\"sync\"\n)\n\nvar bufferPool = sync.Pool{\n\tNew: func() any {\n\t\treturn new(Buffer)\n\t},\n}\n\n// GetBuffer creates and returns a new buffer if the writer is not already a buffer,\n// or returns the existing buffer if it is.\nfunc GetBuffer(w io.Writer) (b *Buffer, existing bool) {\n\tif w == nil {\n\t\treturn nil, false\n\t}\n\tb, ok := w.(*Buffer)\n\tif ok {\n\t\treturn b, true\n\t}\n\tb = bufferPool.Get().(*Buffer)\n\tb.Reset(w)\n\treturn b, false\n}\n\n// ReleaseBuffer flushes the buffer and returns it to the pool.\nfunc ReleaseBuffer(w io.Writer) (err error) {\n\tb, ok := w.(*Buffer)\n\tif !ok {\n\t\treturn nil\n\t}\n\terr = b.Flush()\n\tbufferPool.Put(b)\n\treturn err\n}\n"
  },
  {
    "path": "runtime/bufferpool_test.go",
    "content": "package runtime\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n)\n\nfunc TestBufferPool(t *testing.T) {\n\tt.Run(\"can get a buffer from the pool\", func(t *testing.T) {\n\t\tw, existing := GetBuffer(new(bytes.Buffer))\n\t\tif w == nil {\n\t\t\tt.Error(\"expected a buffer, got nil\")\n\t\t}\n\t\tif existing {\n\t\t\tt.Error(\"expected a new buffer, got an existing buffer\")\n\t\t}\n\t\terr := ReleaseBuffer(w)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"can get an existing buffer from the pool\", func(t *testing.T) {\n\t\tw, existing := GetBuffer(new(bytes.Buffer))\n\t\tif w == nil {\n\t\t\tt.Error(\"expected a buffer, got nil\")\n\t\t}\n\t\tif existing {\n\t\t\tt.Error(\"expected a new buffer, got an existing buffer\")\n\t\t}\n\n\t\tw, existing = GetBuffer(w)\n\t\tif w == nil {\n\t\t\tt.Error(\"expected a buffer, got nil\")\n\t\t}\n\t\tif !existing {\n\t\t\tt.Error(\"expected an existing buffer, got a new buffer\")\n\t\t}\n\n\t\terr := ReleaseBuffer(w)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"can release any writer without error\", func(t *testing.T) {\n\t\terr := ReleaseBuffer(new(bytes.Buffer))\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t}\n\t})\n\tt.Run(\"attempting to buffer a nil writer returns nil\", func(t *testing.T) {\n\t\tw, existing := GetBuffer(nil)\n\t\tif w != nil {\n\t\t\tt.Error(\"expected nil, got a buffer\")\n\t\t}\n\t\tif existing {\n\t\t\tt.Error(\"expected nil, got an existing buffer\")\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "runtime/builder.go",
    "content": "package runtime\n\nimport \"strings\"\n\n// GetBuilder returns a strings.Builder.\nfunc GetBuilder() (sb strings.Builder) {\n\treturn sb\n}\n"
  },
  {
    "path": "runtime/builder_test.go",
    "content": "package runtime\n\nimport \"testing\"\n\nfunc TestGetBuilder(t *testing.T) {\n\tsb := GetBuilder()\n\tsb.WriteString(\"test\")\n\tif sb.String() != \"test\" {\n\t\tt.Errorf(\"expected \\\"test\\\", got %q\", sb.String())\n\t}\n}\n"
  },
  {
    "path": "runtime/fuzzing/fuzz.templ",
    "content": "package fuzzing\n\ntempl String(v any) {\n\t<script>\n\t\tfunction logValue() {\n\t\t\tconsole.log(\"{{ v }}\");\n\t\t\treturn \"result_ok\";\n\t\t}\n\t</script>\n}\n\ntempl Any(v any) {\n\t<script>\n\t\tfunction logValue() {\n\t\t\tconsole.log({{ v }});\n\t\t\treturn \"result_ok\";\n\t\t}\n\t</script>\n}\n"
  },
  {
    "path": "runtime/fuzzing/fuzz_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage fuzzing\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc String(v any) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<script>\\n\\t\\tfunction logValue() {\\n\\t\\t\\tconsole.log(\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err := templruntime.ScriptContentInsideStringLiteral(v)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `runtime/fuzzing/fuzz.templ`, Line: 6, Col: 20}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\");\\n\\t\\t\\treturn \\\"result_ok\\\";\\n\\t\\t}\\n\\t</script>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc Any(v any) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"<script>\\n\\t\\tfunction logValue() {\\n\\t\\t\\tconsole.log(\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err := templruntime.ScriptContentOutsideStringLiteral(v)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `runtime/fuzzing/fuzz.templ`, Line: 15, Col: 19}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var4)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \");\\n\\t\\t\\treturn \\\"result_ok\\\";\\n\\t\\t}\\n\\t</script>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "runtime/fuzzing/fuzz_test.go",
    "content": "package fuzzing\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"golang.org/x/net/html\"\n\n\tv8 \"rogchap.com/v8go\"\n)\n\nvar iso = v8.NewIsolate()\n\nvar testcases = []string{\n\t\"hello\",\n\t\"<script>console.log('hello')</script>\",\n\t\"text data\\n can contain all sorts of \\\"characters\\\" & symbols\",\n\t\"123\",\n\t\"</script>\",\n}\n\nfunc FuzzComponentString(f *testing.F) {\n\tfor _, tc := range testcases {\n\t\tf.Add([]byte(tc))\n\t}\n\tf.Fuzz(func(t *testing.T, v []byte) {\n\t\t// Render template.\n\t\tbuf := new(strings.Builder)\n\n\t\tvalues := []any{\n\t\t\tstring(v),\n\t\t\t[]string{string(v)},\n\t\t\tmap[string]string{\"value\": string(v)},\n\t\t}\n\t\tfor _, value := range values {\n\t\t\tbuf.Reset()\n\t\t\tif err := String(value).Render(context.Background(), buf); err != nil {\n\t\t\t\tt.Skip(err)\n\t\t\t}\n\t\t\trunTest(t, buf.String())\n\t\t}\n\t})\n}\n\nfunc FuzzComponentAny(f *testing.F) {\n\tfor _, tc := range testcases {\n\t\tjsonValue, err := json.Marshal(tc)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tf.Add(jsonValue)\n\t}\n\tf.Fuzz(func(t *testing.T, v []byte) {\n\t\t// Render template.\n\t\tbuf := new(strings.Builder)\n\n\t\tvalues := []any{\n\t\t\tstring(v),\n\t\t\t[]string{string(v)},\n\t\t\tmap[string]string{\"value\": string(v)},\n\t\t}\n\t\tfor _, value := range values {\n\t\t\tbuf.Reset()\n\t\t\tif err := Any(value).Render(context.Background(), buf); err != nil {\n\t\t\t\tt.Skip(err)\n\t\t\t}\n\t\t\trunTest(t, buf.String())\n\t\t}\n\t})\n}\n\nfunc getFirstScript(n *html.Node) *html.Node {\n\tif n.Data == \"script\" {\n\t\treturn n\n\t}\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tif s := getFirstScript(c); s != nil {\n\t\t\treturn s\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc runTest(t *testing.T, templateOutput string) {\n\t// Parse HTML.\n\tn, err := html.Parse(strings.NewReader(templateOutput))\n\tif err != nil {\n\t\tt.Fatalf(\"failed to parse HTML: %v\", err)\n\t}\n\tsn := getFirstScript(n)\n\tif sn == nil {\n\t\tt.Fatalf(\"no script tag found\")\n\t}\n\n\t// Extract JavaScript.\n\tscript := sn.FirstChild.Data\n\n\t// Run JavaScript.\n\tv8ctx := v8.NewContext(iso)\n\tif _, err = v8ctx.RunScript(script, \"component.js\"); err != nil {\n\t\tt.Fatalf(\"failed to parse script: %v\", err)\n\t}\n\tif _, err = v8ctx.RunScript(\"const result = logValue()\", \"component.js\"); err != nil {\n\t\tt.Fatalf(\"failed to get value: %v\", err)\n\t}\n\tactual, err := v8ctx.RunScript(\"result\", \"component.js\")\n\tif err != nil {\n\t\tt.Fatalf(\"failed to get result: %v\", err)\n\t}\n\tdefer v8ctx.Close()\n\n\t// Assert.\n\tif !actual.IsString() {\n\t\tt.Fatalf(\"expected boolean, got %T\", actual.Object().Value)\n\t}\n\tif actual.String() != \"result_ok\" {\n\t\tt.Fatalf(\"expected 'result_ok', got %v\", actual.Boolean())\n\t}\n}\n"
  },
  {
    "path": "runtime/fuzzing/go.mod",
    "content": "module github.com/a-h/templ/runtime/fuzzing\n\ngo 1.23.3\n\nrequire (\n\tgithub.com/a-h/templ v0.3.833\n\tgolang.org/x/net v0.42.0\n)\n\nrequire rogchap.com/v8go v0.9.0\n\nreplace github.com/a-h/templ => ../..\n"
  },
  {
    "path": "runtime/fuzzing/go.sum",
    "content": "github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngolang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=\ngolang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=\nrogchap.com/v8go v0.9.0 h1:wYbUCO4h6fjTamziHrzyrPnpFNuzPpjZY+nfmZjNaew=\nrogchap.com/v8go v0.9.0/go.mod h1:MxgP3pL2MW4dpme/72QRs8sgNMmM0pRc8DPhcuLWPAs=\n"
  },
  {
    "path": "runtime/fuzzing/testdata/fuzz/FuzzComponentAny/02bc261247f1267d",
    "content": "go test fuzz v1\n[]byte(\"{\\\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxaluex\")\n"
  },
  {
    "path": "runtime/fuzzing/testdata/fuzz/FuzzComponentAny/0e3d2540388fc8bd",
    "content": "go test fuzz v1\n[]byte(\"{\\\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxaluex\")\n"
  },
  {
    "path": "runtime/fuzzing/testdata/fuzz/FuzzComponentAny/0ed510998a1c1a4e",
    "content": "go test fuzz v1\n[]byte(\"{\\\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxalue\\\"x\")\n"
  },
  {
    "path": "runtime/fuzzing/testdata/fuzz/FuzzComponentAny/926b62a033ecc0fd",
    "content": "go test fuzz v1\n[]byte(\"000000000000000000000000000000000000000000000\\x128\\x06\\xef\\x01\\xb40000000\")\n"
  },
  {
    "path": "runtime/fuzzing/testdata/fuzz/FuzzComponentString/4a59bdc98ee75491",
    "content": "go test fuzz v1\n[]byte(\"&&&&\\\"0&&&&&00&00&&&0&00&0&8&&&\")\n"
  },
  {
    "path": "runtime/fuzzing/testdata/fuzz/FuzzComponentString/66658924a0ea89b6",
    "content": "go test fuzz v1\n[]byte(\"\\\"\\xf5\\x9a\\xb7\\\"\\x8a\\\"\\\"\\x9a\\x9a\\xf5\\x9a\\xb7\\\"\\x8a\\x8a\\\"\\\"\\\"\\\"\\\"\\\"\")\n"
  },
  {
    "path": "runtime/fuzzing/testdata/fuzz/FuzzComponentString/9fc8b4df9a42170c",
    "content": "go test fuzz v1\n[]byte(\"\\x00\\xa5\\x05\\x93ϵ\\xa0\\xa0\\xfe\\xee\\xcf\\x1e\\xa7\\xcb\\xde\\x13\\x1c\\xb9\\xb7\\xc2\\xca^\\xb1\\xb3\\xc0\\x1a\\x01\\xbb\\xae\\x89\\x83\\x87\\x89\\xbb\\x1d\\xbd\\xb7\\x95\\x8e\\\\\\x91\\xe6\\x10\\xe4\\xdf\\xec\\xf0\\xcd\\xe6\\a\\xea/\\xa2\\xbb\\xbd\\xef\\xf9\\v\\x87\\xd5\\xc0\\xe6\\xa4\\xdc\\x02\\xf8\\xfc\\x9dأ\\xc2\\\\\\xc4\\xf3\\x87\\x04\\x01\\x18\\x16\\xc3\\xe1\\xbc\\xc3\\xc9\\x12\\xd5\\xc3\\xf9\\r\\x13\\x1a\\xdbx\\xb6\\xe8\\xe2&\\xbb\\x81'\\xea'\\xc56\\xb7\\xf3;\\xb3\\xdb\\xed\\x8c.\\xb8\\xd4\\xcc\\xfe\\xbcإ\\xf0\\xb6\\xf3\\xf1\\xdeF\\xb8\\x12\\b\\x9f\\xb9\\xa5\\xb4&\\xa1\\xea\\a\\x17ɕ\\x0e\\xe9\\xf9\\xe0\\xb6K\\x93\\xdd\\xee<\\xf6\\xda\\t\\xac\\xa4\\xb9\\xb9ƽ\\x98\\xa6\\xeb\\xc5\\xfe\\v\\xb9\\xdb\\xc7\\xc4\\x05\\v\\xf5\\xb4߫\\xd2\\xc6\\xe7\\x0f⨍\\xb5\\xb4\\xc3\\xcb\\x17\\xc1\\xf9\\x95\\x13\\xfc\\xd4\\x1a\\xcfԈ\\xda\\x17\\xaa\\xd1'\\b\\xe9\\t\\xb4\\xec\\xc2ɹ\\xe0\\v\\x14\\xd4h\\xa6\\x9c\\x82\\xf0\\x06\\xd8?\\x8a\\xf0\\xc5\\xed\\xd1\\xd2\\xdf\\xfb\\x02\\xab\\x84\\xf2M\\xb5ò\\xe9\\xc8\\xf3\\x1c\\xae\\xfe\\xee\\xe5쪢\\xf6\\xe9[\\x9e\\xcc\\x13\\x1d\\xea\\xb5\\x1e\\xe7<\\xc7\\xf7\\xac\\v\\xba\\x15\\xcd\\xdd\\xe0\\x1e\\xf7\\xf9\\x94\\x83\\xcd\\xc7\\xe5\\xad\\xc1\\xca?\\xb9\\xe7\\x06\\xb1\\xd5\\x12\")\n"
  },
  {
    "path": "runtime/runtime.go",
    "content": "package runtime\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/a-h/templ\"\n)\n\n// GeneratedComponentInput is used to avoid generated code needing to import the `context` and `io` packages.\ntype GeneratedComponentInput struct {\n\tContext context.Context\n\tWriter  io.Writer\n}\n\n// GeneratedTemplate is used to avoid generated code needing to import the `context` and `io` packages.\nfunc GeneratedTemplate(f func(GeneratedComponentInput) error) templ.Component {\n\treturn templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t\treturn f(GeneratedComponentInput{ctx, w})\n\t})\n}\n"
  },
  {
    "path": "runtime/runtime_test.go",
    "content": "package runtime\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc TestGeneratedTemplate(t *testing.T) {\n\tf := func(input GeneratedComponentInput) error {\n\t\t_, err := input.Writer.Write([]byte(\"Hello, World!\"))\n\t\treturn err\n\t}\n\tsb := new(strings.Builder)\n\terr := GeneratedTemplate(f).Render(context.Background(), sb)\n\tif err != nil {\n\t\tt.Errorf(\"unexpected error: %v\", err)\n\t}\n\tif sb.String() != \"Hello, World!\" {\n\t\tt.Errorf(\"expected \\\"Hello, World!\\\", got %q\", sb.String())\n\t}\n}\n"
  },
  {
    "path": "runtime/scriptelement.go",
    "content": "package runtime\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nfunc ScriptContentInsideStringLiteral[T any](v T, errs ...error) (string, error) {\n\treturn scriptContent(v, true, errs...)\n}\n\nfunc ScriptContentOutsideStringLiteral[T any](v T, errs ...error) (string, error) {\n\treturn scriptContent(v, false, errs...)\n}\n\nfunc scriptContent[T any](v T, insideStringLiteral bool, errs ...error) (string, error) {\n\tif errors.Join(errs...) != nil {\n\t\treturn \"\", errors.Join(errs...)\n\t}\n\tif vs, ok := any(v).(string); ok && insideStringLiteral {\n\t\treturn replace(vs, jsStrReplacementTable), nil\n\t}\n\tjd, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif insideStringLiteral {\n\t\treturn replace(string(jd), jsStrReplacementTable), nil\n\t}\n\treturn string(jd), nil\n}\n\n// See https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/html/template/js.go\n\n// replace replaces each rune r of s with replacementTable[r], provided that\n// r < len(replacementTable). If replacementTable[r] is the empty string then\n// no replacement is made.\n// It also replaces runes U+2028 and U+2029 with the raw strings `\\u2028` and\n// `\\u2029`.\nfunc replace(s string, replacementTable []string) string {\n\tvar b strings.Builder\n\tr, w, written := rune(0), 0, 0\n\tfor i := 0; i < len(s); i += w {\n\t\t// See comment in htmlEscaper.\n\t\tr, w = utf8.DecodeRuneInString(s[i:])\n\t\tvar repl string\n\t\tswitch {\n\t\tcase int(r) < len(lowUnicodeReplacementTable):\n\t\t\trepl = lowUnicodeReplacementTable[r]\n\t\tcase int(r) < len(replacementTable) && replacementTable[r] != \"\":\n\t\t\trepl = replacementTable[r]\n\t\tcase r == '\\u2028':\n\t\t\trepl = `\\u2028`\n\t\tcase r == '\\u2029':\n\t\t\trepl = `\\u2029`\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\t\tif written == 0 {\n\t\t\tb.Grow(len(s))\n\t\t}\n\t\tb.WriteString(s[written:i])\n\t\tb.WriteString(repl)\n\t\twritten = i + w\n\t}\n\tif written == 0 {\n\t\treturn s\n\t}\n\tb.WriteString(s[written:])\n\treturn b.String()\n}\n\nvar lowUnicodeReplacementTable = []string{\n\t0: `\\u0000`, 1: `\\u0001`, 2: `\\u0002`, 3: `\\u0003`, 4: `\\u0004`, 5: `\\u0005`, 6: `\\u0006`,\n\t'\\a': `\\u0007`,\n\t'\\b': `\\u0008`,\n\t'\\t': `\\t`,\n\t'\\n': `\\n`,\n\t'\\v': `\\u000b`, // \"\\v\" == \"v\" on IE 6.\n\t'\\f': `\\f`,\n\t'\\r': `\\r`,\n\t0xe:  `\\u000e`, 0xf: `\\u000f`, 0x10: `\\u0010`, 0x11: `\\u0011`, 0x12: `\\u0012`, 0x13: `\\u0013`,\n\t0x14: `\\u0014`, 0x15: `\\u0015`, 0x16: `\\u0016`, 0x17: `\\u0017`, 0x18: `\\u0018`, 0x19: `\\u0019`,\n\t0x1a: `\\u001a`, 0x1b: `\\u001b`, 0x1c: `\\u001c`, 0x1d: `\\u001d`, 0x1e: `\\u001e`, 0x1f: `\\u001f`,\n}\n\nvar jsStrReplacementTable = []string{\n\t0:    `\\u0000`,\n\t'\\t': `\\t`,\n\t'\\n': `\\n`,\n\t'\\v': `\\u000b`, // \"\\v\" == \"v\" on IE 6.\n\t'\\f': `\\f`,\n\t'\\r': `\\r`,\n\t// Encode HTML specials as hex so the output can be embedded\n\t// in HTML attributes without further encoding.\n\t'\"':  `\\u0022`,\n\t'`':  `\\u0060`,\n\t'&':  `\\u0026`,\n\t'\\'': `\\u0027`,\n\t'+':  `\\u002b`,\n\t'/':  `\\/`,\n\t'<':  `\\u003c`,\n\t'>':  `\\u003e`,\n\t'\\\\': `\\\\`,\n}\n"
  },
  {
    "path": "runtime/scriptelement_test.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"testing\"\n)\n\nfunc TestScriptContent(t *testing.T) {\n\ttests := []struct {\n\t\tname                         string\n\t\tinput                        any\n\t\texpectedInsideStringLiteral  string\n\t\texpectedOutsideStringLiteral string\n\t}{\n\t\t{\n\t\t\tname:                         \"string\",\n\t\t\tinput:                        \"hello\",\n\t\t\texpectedInsideStringLiteral:  `hello`,\n\t\t\texpectedOutsideStringLiteral: `\"hello\"`,\n\t\t},\n\t\t{\n\t\t\tname:                         \"string with single quotes\",\n\t\t\tinput:                        \"hello 'world'\",\n\t\t\texpectedInsideStringLiteral:  `hello \\u0027world\\u0027`,\n\t\t\texpectedOutsideStringLiteral: `\"hello 'world'\"`,\n\t\t},\n\t\t{\n\t\t\tname:                         \"string with double quotes\",\n\t\t\tinput:                        \"hello \\\"world\\\"\",\n\t\t\texpectedInsideStringLiteral:  `hello \\u0022world\\u0022`,\n\t\t\texpectedOutsideStringLiteral: `\"hello \\\"world\\\"\"`,\n\t\t},\n\t\t{\n\t\t\tname:                         \"string with backticks\",\n\t\t\tinput:                        \"hello `world`\",\n\t\t\texpectedInsideStringLiteral:  `hello \\u0060world\\u0060`,\n\t\t\texpectedOutsideStringLiteral: \"\\\"hello `world`\\\"\",\n\t\t},\n\t\t{\n\t\t\tname:                         \"int\",\n\t\t\tinput:                        1,\n\t\t\texpectedInsideStringLiteral:  `1`,\n\t\t\texpectedOutsideStringLiteral: `1`,\n\t\t},\n\t\t{\n\t\t\tname:                         \"float\",\n\t\t\tinput:                        1.1,\n\t\t\texpectedInsideStringLiteral:  `1.1`,\n\t\t\texpectedOutsideStringLiteral: `1.1`,\n\t\t},\n\t\t{\n\t\t\tname:                         \"bool\",\n\t\t\tinput:                        true,\n\t\t\texpectedInsideStringLiteral:  `true`,\n\t\t\texpectedOutsideStringLiteral: `true`,\n\t\t},\n\t\t{\n\t\t\tname:                         \"array\",\n\t\t\tinput:                        []int{1, 2, 3},\n\t\t\texpectedInsideStringLiteral:  `[1,2,3]`,\n\t\t\texpectedOutsideStringLiteral: `[1,2,3]`,\n\t\t},\n\t\t{\n\t\t\tname:                         \"object\",\n\t\t\tinput:                        struct{ Name string }{\"Alice\"},\n\t\t\texpectedInsideStringLiteral:  `{\\u0022Name\\u0022:\\u0022Alice\\u0022}`,\n\t\t\texpectedOutsideStringLiteral: `{\"Name\":\"Alice\"}`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tt.Run(\"inside string literal\", func(t *testing.T) {\n\t\t\t\tactualInsideStringLiteral, err := ScriptContentInsideStringLiteral(tt.input)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatalf(\"unexpected error: %s\", err)\n\t\t\t\t}\n\t\t\t\tif actualInsideStringLiteral != tt.expectedInsideStringLiteral {\n\t\t\t\t\tt.Errorf(\"expected:\\n%s\\ngot:\\n%s\", tt.expectedInsideStringLiteral, actualInsideStringLiteral)\n\t\t\t\t}\n\t\t\t})\n\t\t\tt.Run(\"outside string literal\", func(t *testing.T) {\n\t\t\t\tactualOutsideStringLiteral, err := ScriptContentOutsideStringLiteral(tt.input)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatalf(\"unexpected error: %s\", err)\n\t\t\t\t}\n\t\t\t\tif actualOutsideStringLiteral != tt.expectedOutsideStringLiteral {\n\t\t\t\t\tt.Errorf(\"expected:\\n%s\\ngot:\\n%s\", tt.expectedOutsideStringLiteral, actualOutsideStringLiteral)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n}\n\nfunc TestScriptContentErrors(t *testing.T) {\n\tt.Run(\"inside string literal\", func(t *testing.T) {\n\t\t_, err := ScriptContentInsideStringLiteral(\"s\", errors.New(\"error\"))\n\t\tif err == nil {\n\t\t\tt.Fatal(\"expected error\")\n\t\t}\n\t\tif err.Error() != \"error\" {\n\t\t\tt.Errorf(\"expected error: %s\", err)\n\t\t}\n\t})\n\tt.Run(\"outside string literal\", func(t *testing.T) {\n\t\t_, err := ScriptContentOutsideStringLiteral(\"s\", errors.New(\"error\"))\n\t\tif err == nil {\n\t\t\tt.Fatal(\"expected error\")\n\t\t}\n\t\tif err.Error() != \"error\" {\n\t\t\tt.Errorf(\"expected error: %s\", err)\n\t\t}\n\t})\n\tt.Run(\"unmarshal error\", func(t *testing.T) {\n\t\t_, err := ScriptContentInsideStringLiteral(func() string {\n\t\t\treturn \"hello\"\n\t\t})\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"expected unmarshal error, but got %v\", err)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "runtime/styleattribute.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"html\"\n\t\"maps\"\n\t\"reflect\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/safehtml\"\n)\n\n// SanitizeStyleAttributeValues renders a style attribute value.\n// The supported types are:\n// - string\n// - templ.SafeCSS\n// - map[string]string\n// - map[string]templ.SafeCSSProperty\n// - templ.KeyValue[string, string] - A map of key/values where the key is the CSS property name and the value is the CSS property value.\n// - templ.KeyValue[string, templ.SafeCSSProperty] - A map of key/values where the key is the CSS property name and the value is the CSS property value.\n// - templ.KeyValue[string, bool] - The bool determines whether the value should be included.\n// - templ.KeyValue[templ.SafeCSS, bool] - The bool determines whether the value should be included.\n// - func() (anyOfTheAboveTypes)\n// - func() (anyOfTheAboveTypes, error)\n// - []anyOfTheAboveTypes\n//\n// In the above, templ.SafeCSS and templ.SafeCSSProperty are types that are used to indicate that the value is safe to render as CSS without sanitization.\n// All other types are sanitized before rendering.\n//\n// If an error is returned by any function, or a non-nil error is included in the input, the error is returned.\nfunc SanitizeStyleAttributeValues(values ...any) (string, error) {\n\tif err := getJoinedErrorsFromValues(values...); err != nil {\n\t\treturn \"\", err\n\t}\n\tsb := new(strings.Builder)\n\tfor _, v := range values {\n\t\tif v == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err := sanitizeStyleAttributeValue(sb, v); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\treturn sb.String(), nil\n}\n\nfunc sanitizeStyleAttributeValue(sb *strings.Builder, v any) error {\n\t// Process concrete types.\n\tswitch v := v.(type) {\n\tcase string:\n\t\treturn processString(sb, v)\n\n\tcase templ.SafeCSS:\n\t\treturn processSafeCSS(sb, v)\n\n\tcase map[string]string:\n\t\treturn processStringMap(sb, v)\n\n\tcase map[string]templ.SafeCSSProperty:\n\t\treturn processSafeCSSPropertyMap(sb, v)\n\n\tcase templ.KeyValue[string, string]:\n\t\treturn processStringKV(sb, v)\n\n\tcase templ.KeyValue[string, bool]:\n\t\tif v.Value {\n\t\t\treturn processString(sb, v.Key)\n\t\t}\n\t\treturn nil\n\n\tcase templ.KeyValue[templ.SafeCSS, bool]:\n\t\tif v.Value {\n\t\t\treturn processSafeCSS(sb, v.Key)\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Fall back to reflection.\n\n\t// Handle functions first using reflection.\n\tif handled, err := handleFuncWithReflection(sb, v); handled {\n\t\treturn err\n\t}\n\n\t// Handle slices using reflection before concrete types.\n\tif handled, err := handleSliceWithReflection(sb, v); handled {\n\t\treturn err\n\t}\n\n\t_, err := sb.WriteString(TemplUnsupportedStyleAttributeValue)\n\treturn err\n}\n\nfunc processSafeCSS(sb *strings.Builder, v templ.SafeCSS) error {\n\tif v == \"\" {\n\t\treturn nil\n\t}\n\tsb.WriteString(html.EscapeString(string(v)))\n\tif !strings.HasSuffix(string(v), \";\") {\n\t\tsb.WriteRune(';')\n\t}\n\treturn nil\n}\n\nfunc processString(sb *strings.Builder, v string) error {\n\tif v == \"\" {\n\t\treturn nil\n\t}\n\tsanitized := strings.TrimSpace(safehtml.SanitizeStyleValue(v))\n\tsb.WriteString(html.EscapeString(sanitized))\n\tif !strings.HasSuffix(sanitized, \";\") {\n\t\tsb.WriteRune(';')\n\t}\n\treturn nil\n}\n\nvar ErrInvalidStyleAttributeFunctionSignature = errors.New(\"invalid function signature, should be in the form func() (string, error)\")\n\n// handleFuncWithReflection handles functions using reflection.\nfunc handleFuncWithReflection(sb *strings.Builder, v any) (bool, error) {\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Func {\n\t\treturn false, nil\n\t}\n\n\tt := rv.Type()\n\tif t.NumIn() != 0 || (t.NumOut() != 1 && t.NumOut() != 2) {\n\t\treturn false, ErrInvalidStyleAttributeFunctionSignature\n\t}\n\n\t// Check the types of the return values\n\tif t.NumOut() == 2 {\n\t\t// Ensure the second return value is of type `error`\n\t\tsecondReturnType := t.Out(1)\n\t\tif !secondReturnType.Implements(reflect.TypeOf((*error)(nil)).Elem()) {\n\t\t\treturn false, fmt.Errorf(\"second return value must be of type error, got %v\", secondReturnType)\n\t\t}\n\t}\n\n\tresults := rv.Call(nil)\n\n\tif t.NumOut() == 2 {\n\t\t// Check if the second return value is an error\n\t\tif errVal := results[1].Interface(); errVal != nil {\n\t\t\tif err, ok := errVal.(error); ok && err != nil {\n\t\t\t\treturn true, err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true, sanitizeStyleAttributeValue(sb, results[0].Interface())\n}\n\n// handleSliceWithReflection handles slices using reflection.\nfunc handleSliceWithReflection(sb *strings.Builder, v any) (bool, error) {\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Slice {\n\t\treturn false, nil\n\t}\n\tfor i := range rv.Len() {\n\t\telem := rv.Index(i).Interface()\n\t\tif err := sanitizeStyleAttributeValue(sb, elem); err != nil {\n\t\t\treturn true, err\n\t\t}\n\t}\n\treturn true, nil\n}\n\n// processStringMap processes a map[string]string.\nfunc processStringMap(sb *strings.Builder, m map[string]string) error {\n\tfor _, name := range slices.Sorted(maps.Keys(m)) {\n\t\tname, value := safehtml.SanitizeCSS(name, m[name])\n\t\tsb.WriteString(html.EscapeString(name))\n\t\tsb.WriteRune(':')\n\t\tsb.WriteString(html.EscapeString(value))\n\t\tsb.WriteRune(';')\n\t}\n\treturn nil\n}\n\n// processSafeCSSPropertyMap processes a map[string]templ.SafeCSSProperty.\nfunc processSafeCSSPropertyMap(sb *strings.Builder, m map[string]templ.SafeCSSProperty) error {\n\tfor _, name := range slices.Sorted(maps.Keys(m)) {\n\t\tsb.WriteString(html.EscapeString(safehtml.SanitizeCSSProperty(name)))\n\t\tsb.WriteRune(':')\n\t\tsb.WriteString(html.EscapeString(string(m[name])))\n\t\tsb.WriteRune(';')\n\t}\n\treturn nil\n}\n\n// processStringKV processes a templ.KeyValue[string, string].\nfunc processStringKV(sb *strings.Builder, kv templ.KeyValue[string, string]) error {\n\tname, value := safehtml.SanitizeCSS(kv.Key, kv.Value)\n\tsb.WriteString(html.EscapeString(name))\n\tsb.WriteRune(':')\n\tsb.WriteString(html.EscapeString(value))\n\tsb.WriteRune(';')\n\treturn nil\n}\n\n// getJoinedErrorsFromValues collects and joins errors from the input values.\nfunc getJoinedErrorsFromValues(values ...any) error {\n\tvar errs []error\n\tfor _, v := range values {\n\t\tif err, ok := v.(error); ok {\n\t\t\terrs = append(errs, err)\n\t\t}\n\t}\n\treturn errors.Join(errs...)\n}\n\n// TemplUnsupportedStyleAttributeValue is the default value returned for unsupported types.\nvar TemplUnsupportedStyleAttributeValue = \"zTemplUnsupportedStyleAttributeValue:Invalid;\"\n"
  },
  {
    "path": "runtime/styleattribute_test.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nvar (\n\terr1 = errors.New(\"error 1\")\n\terr2 = errors.New(\"error 2\")\n)\n\nfunc TestSanitizeStyleAttribute(t *testing.T) {\n\ttests := []struct {\n\t\tname        string\n\t\tinput       []any\n\t\texpected    string\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname:        \"errors are returned\",\n\t\t\tinput:       []any{err1},\n\t\t\texpectedErr: err1,\n\t\t},\n\t\t{\n\t\t\tname:        \"multiple errors are joined and returned\",\n\t\t\tinput:       []any{err1, err2},\n\t\t\texpectedErr: errors.Join(err1, err2),\n\t\t},\n\t\t{\n\t\t\tname: \"functions that return errors return the error\",\n\t\t\tinput: []any{\n\t\t\t\t\"color:red\",\n\t\t\t\tfunc() (string, error) { return \"\", err1 },\n\t\t\t},\n\t\t\texpectedErr: err1,\n\t\t},\n\n\t\t// string\n\t\t{\n\t\t\tname:     \"strings: are allowed\",\n\t\t\tinput:    []any{\"color:red;background-color:blue;\"},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"strings: have semi-colons appended if missing\",\n\t\t\tinput:    []any{\"color:red;background-color:blue\"},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"strings: empty strings are elided\",\n\t\t\tinput:    []any{\"\"},\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"strings: are sanitized\",\n\t\t\tinput:    []any{\"</style><script>alert('xss')</script>\"},\n\t\t\texpected: `\\00003C/style&gt;\\00003Cscript&gt;alert(&#39;xss&#39;)\\00003C/script&gt;;`,\n\t\t},\n\n\t\t// templ.SafeCSS\n\t\t{\n\t\t\tname:     \"SafeCSS: is allowed\",\n\t\t\tinput:    []any{templ.SafeCSS(\"color:red;background-color:blue;\")},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"SafeCSS: have semi-colons appended if missing\",\n\t\t\tinput:    []any{templ.SafeCSS(\"color:red;background-color:blue\")},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"SafeCSS: empty strings are elided\",\n\t\t\tinput:    []any{templ.SafeCSS(\"\")},\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"SafeCSS: is escaped, but not sanitized\",\n\t\t\tinput:    []any{templ.SafeCSS(\"</style>\")},\n\t\t\texpected: `&lt;/style&gt;;`,\n\t\t},\n\n\t\t// map[string]string\n\t\t{\n\t\t\tname:     \"map[string]string: is allowed\",\n\t\t\tinput:    []any{map[string]string{\"color\": \"red\", \"background-color\": \"blue\"}},\n\t\t\texpected: \"background-color:blue;color:red;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"map[string]string: keys are sorted\",\n\t\t\tinput:    []any{map[string]string{\"z-index\": \"1\", \"color\": \"red\", \"background-color\": \"blue\"}},\n\t\t\texpected: \"background-color:blue;color:red;z-index:1;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"map[string]string: empty names are invalid\",\n\t\t\tinput:    []any{map[string]string{\"\": \"red\", \"background-color\": \"blue\"}},\n\t\t\texpected: \"zTemplUnsafeCSSPropertyName:zTemplUnsafeCSSPropertyValue;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"map[string]string: keys and values are sanitized\",\n\t\t\tinput:    []any{map[string]string{\"color\": \"</style>\", \"background-color\": \"blue\"}},\n\t\t\texpected: \"background-color:blue;color:zTemplUnsafeCSSPropertyValue;\",\n\t\t},\n\n\t\t// map[string]templ.SafeCSSProperty\n\t\t{\n\t\t\tname:     \"map[string]templ.SafeCSSProperty: is allowed\",\n\t\t\tinput:    []any{map[string]templ.SafeCSSProperty{\"color\": \"red\", \"background-color\": \"blue\"}},\n\t\t\texpected: \"background-color:blue;color:red;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"map[string]templ.SafeCSSProperty: keys are sorted\",\n\t\t\tinput:    []any{map[string]templ.SafeCSSProperty{\"z-index\": \"1\", \"color\": \"red\", \"background-color\": \"blue\"}},\n\t\t\texpected: \"background-color:blue;color:red;z-index:1;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"map[string]templ.SafeCSSProperty: empty names are invalid\",\n\t\t\tinput:    []any{map[string]templ.SafeCSSProperty{\"\": \"red\", \"background-color\": \"blue\"}},\n\t\t\texpected: \"zTemplUnsafeCSSPropertyName:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"map[string]templ.SafeCSSProperty: keys are sanitized, but not values\",\n\t\t\tinput:    []any{map[string]templ.SafeCSSProperty{\"color\": \"</style>\", \"</style>\": \"blue\"}},\n\t\t\texpected: \"zTemplUnsafeCSSPropertyName:blue;color:&lt;/style&gt;;\",\n\t\t},\n\n\t\t// templ.KeyValue[string, string]\n\t\t{\n\t\t\tname:     \"KeyValue[string, string]: is allowed\",\n\t\t\tinput:    []any{templ.KV(\"color\", \"red\"), templ.KV(\"background-color\", \"blue\")},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[string, string]: keys and values are sanitized\",\n\t\t\tinput:    []any{templ.KV(\"color\", \"</style>\"), templ.KV(\"</style>\", \"blue\")},\n\t\t\texpected: \"color:zTemplUnsafeCSSPropertyValue;zTemplUnsafeCSSPropertyName:zTemplUnsafeCSSPropertyValue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[string, string]: empty names are invalid\",\n\t\t\tinput:    []any{templ.KV(\"\", \"red\"), templ.KV(\"background-color\", \"blue\")},\n\t\t\texpected: \"zTemplUnsafeCSSPropertyName:zTemplUnsafeCSSPropertyValue;background-color:blue;\",\n\t\t},\n\n\t\t// templ.KeyValue[string, templ.SafeCSSProperty]\n\t\t{\n\t\t\tname:     \"KeyValue[string, templ.SafeCSSProperty]: is allowed\",\n\t\t\tinput:    []any{templ.KV(\"color\", \"red\"), templ.KV(\"background-color\", \"blue\")},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[string, templ.SafeCSSProperty]: keys are sanitized, but not values\",\n\t\t\tinput:    []any{templ.KV(\"color\", \"</style>\"), templ.KV(\"</style>\", \"blue\")},\n\t\t\texpected: \"color:zTemplUnsafeCSSPropertyValue;zTemplUnsafeCSSPropertyName:zTemplUnsafeCSSPropertyValue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[string, templ.SafeCSSProperty]: empty names are invalid\",\n\t\t\tinput:    []any{templ.KV(\"\", \"red\"), templ.KV(\"background-color\", \"blue\")},\n\t\t\texpected: \"zTemplUnsafeCSSPropertyName:zTemplUnsafeCSSPropertyValue;background-color:blue;\",\n\t\t},\n\n\t\t// templ.KeyValue[string, bool]\n\t\t{\n\t\t\tname:     \"KeyValue[string, bool]: is allowed\",\n\t\t\tinput:    []any{templ.KV(\"color:red\", true), templ.KV(\"background-color:blue\", true), templ.KV(\"color:blue\", false)},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[string, bool]: false values are elided\",\n\t\t\tinput:    []any{templ.KV(\"color:red\", false), templ.KV(\"background-color:blue\", true)},\n\t\t\texpected: \"background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[string, bool]: keys are sanitized as per strings\",\n\t\t\tinput:    []any{templ.KV(\"</style>\", true), templ.KV(\"background-color:blue\", true)},\n\t\t\texpected: \"\\\\00003C/style&gt;;background-color:blue;\",\n\t\t},\n\n\t\t// templ.KeyValue[templ.SafeCSS, bool]\n\t\t{\n\t\t\tname:     \"KeyValue[templ.SafeCSS, bool]: is allowed\",\n\t\t\tinput:    []any{templ.KV(templ.SafeCSS(\"color:red\"), true), templ.KV(templ.SafeCSS(\"background-color:blue\"), true), templ.KV(templ.SafeCSS(\"color:blue\"), false)},\n\t\t\texpected: \"color:red;background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[templ.SafeCSS, bool]: false values are elided\",\n\t\t\tinput:    []any{templ.KV(templ.SafeCSS(\"color:red\"), false), templ.KV(templ.SafeCSS(\"background-color:blue\"), true)},\n\t\t\texpected: \"background-color:blue;\",\n\t\t},\n\t\t{\n\t\t\tname:     \"KeyValue[templ.SafeCSS, bool]: keys are not sanitized\",\n\t\t\tinput:    []any{templ.KV(templ.SafeCSS(\"</style>\"), true), templ.KV(templ.SafeCSS(\"background-color:blue\"), true)},\n\t\t\texpected: \"&lt;/style&gt;;background-color:blue;\",\n\t\t},\n\n\t\t// Functions.\n\t\t{\n\t\t\tname: \"func: string\",\n\t\t\tinput: []any{\n\t\t\t\tfunc() string { return \"color:red\" },\n\t\t\t},\n\t\t\texpected: `color:red;`,\n\t\t},\n\t\t{\n\t\t\tname: \"func: string, error - success\",\n\t\t\tinput: []any{\n\t\t\t\tfunc() (string, error) { return \"color:blue\", nil },\n\t\t\t},\n\t\t\texpected: `color:blue;`,\n\t\t},\n\t\t{\n\t\t\tname: \"func: string, error - error\",\n\t\t\tinput: []any{\n\t\t\t\tfunc() (string, error) { return \"\", err1 },\n\t\t\t},\n\t\t\texpectedErr: err1,\n\t\t},\n\t\t{\n\t\t\tname: \"func: invalid signature\",\n\t\t\tinput: []any{\n\t\t\t\tfunc() (string, string) { return \"color:blue\", \"color:blue\" },\n\t\t\t},\n\t\t\texpected: TemplUnsupportedStyleAttributeValue,\n\t\t},\n\t\t{\n\t\t\tname: \"func: only one or two return values are allowed\",\n\t\t\tinput: []any{\n\t\t\t\tfunc() (string, string, string) { return \"color:blue\", \"color:blue\", \"color:blue\" },\n\t\t\t},\n\t\t\texpected: TemplUnsupportedStyleAttributeValue,\n\t\t},\n\n\t\t// Slices.\n\t\t{\n\t\t\tname: \"slices: mixed types are allowed\",\n\t\t\tinput: []any{\n\t\t\t\t[]any{\n\t\t\t\t\t\"color:red\",\n\t\t\t\t\ttempl.KV(\"text-decoration: underline\", true),\n\t\t\t\t\tmap[string]string{\"background\": \"blue\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `color:red;text-decoration: underline;background:blue;`,\n\t\t},\n\t\t{\n\t\t\tname: \"slices: nested slices are allowed\",\n\t\t\tinput: []any{\n\t\t\t\t[]any{\n\t\t\t\t\t[]string{\"color:red\", \"font-size:12px\"},\n\t\t\t\t\t[]templ.SafeCSS{\"margin:0\", \"padding:0\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: `color:red;font-size:12px;margin:0;padding:0;`,\n\t\t},\n\n\t\t// Edge cases.\n\t\t{\n\t\t\tname:     \"edge: nil input\",\n\t\t\tinput:    nil,\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"edge: empty input\",\n\t\t\tinput:    []any{},\n\t\t\texpected: \"\",\n\t\t},\n\t\t{\n\t\t\tname:     \"edge: unsupported type\",\n\t\t\tinput:    []any{42},\n\t\t\texpected: TemplUnsupportedStyleAttributeValue,\n\t\t},\n\t\t{\n\t\t\tname:     \"edge: nil input\",\n\t\t\tinput:    []any{nil},\n\t\t\texpected: \"\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tactual, err := SanitizeStyleAttributeValues(tt.input...)\n\n\t\t\tif tt.expectedErr != nil {\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Fatal(\"expected error but got nil\")\n\t\t\t\t}\n\t\t\t\tif diff := cmp.Diff(tt.expectedErr.Error(), err.Error()); diff != \"\" {\n\t\t\t\t\tt.Errorf(\"error mismatch (-want +got):\\n%s\", diff)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\n\t\t\tif diff := cmp.Diff(tt.expected, actual); diff != \"\" {\n\t\t\t\tt.Errorf(\"result mismatch (-want +got):\\n%s\", diff)\n\t\t\t\tt.Logf(\"Actual result: %q\", actual)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc benchmarkSanitizeAttributeValues(b *testing.B, input ...any) {\n\tfor n := 0; n < b.N; n++ {\n\t\tif _, err := SanitizeStyleAttributeValues(input...); err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\t}\n}\n\nfunc BenchmarkSanitizeAttributeValuesErr(b *testing.B) { benchmarkSanitizeAttributeValues(b, err1) }\nfunc BenchmarkSanitizeAttributeValuesString(b *testing.B) {\n\tbenchmarkSanitizeAttributeValues(b, \"color:red;background-color:blue;\")\n}\nfunc BenchmarkSanitizeAttributeValuesStringSanitized(b *testing.B) {\n\tbenchmarkSanitizeAttributeValues(b, \"</style><script>alert('xss')</script>\")\n}\nfunc BenchmarkSanitizeAttributeValuesSafeCSS(b *testing.B) {\n\tbenchmarkSanitizeAttributeValues(b, templ.SafeCSS(\"color:red;background-color:blue;\"))\n}\nfunc BenchmarkSanitizeAttributeValuesMap(b *testing.B) {\n\tbenchmarkSanitizeAttributeValues(b, map[string]string{\"color\": \"red\", \"background-color\": \"blue\"})\n}\nfunc BenchmarkSanitizeAttributeValuesKV(b *testing.B) {\n\tbenchmarkSanitizeAttributeValues(b, templ.KV(\"color\", \"red\"), templ.KV(\"background-color\", \"blue\"))\n}\nfunc BenchmarkSanitizeAttributeValuesFunc(b *testing.B) {\n\tbenchmarkSanitizeAttributeValues(b, func() string { return \"color:red\" })\n}\n"
  },
  {
    "path": "runtime/watchmode.go",
    "content": "package runtime\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar developmentMode = os.Getenv(\"TEMPL_DEV_MODE\") == \"true\"\n\nvar stringLoaderOnce = sync.OnceValue(func() *StringLoader {\n\treturn NewStringLoader(os.Getenv(\"TEMPL_DEV_MODE_WATCH_ROOT\"))\n})\n\n// WriteString writes the string to the writer. If development mode is enabled\n// s is replaced with the string at the index in the _templ.txt file.\nfunc WriteString(w io.Writer, index int, s string) (err error) {\n\tif developmentMode {\n\t\t_, path, _, _ := runtime.Caller(1)\n\t\tif !strings.HasSuffix(path, \"_templ.go\") {\n\t\t\treturn errors.New(\"templ: attempt to use WriteString from a non templ file\")\n\t\t}\n\t\ts, err = stringLoaderOnce().GetWatchedString(path, index, s)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"templ: failed to get watched string: %w\", err)\n\t\t}\n\t}\n\t_, err = io.WriteString(w, s)\n\treturn err\n}\n\nfunc GetDevModeTextFileName(templFileName string) string {\n\tif prefix, ok := strings.CutSuffix(templFileName, \"_templ.go\"); ok {\n\t\ttemplFileName = prefix + \".templ\"\n\t}\n\tabsFileName, err := filepath.Abs(templFileName)\n\tif err != nil {\n\t\tabsFileName = templFileName\n\t}\n\tabsFileName, err = filepath.EvalSymlinks(absFileName)\n\tif err != nil {\n\t\tabsFileName = templFileName\n\t}\n\tabsFileName = normalizePath(absFileName)\n\n\thashedFileName := sha256.Sum256([]byte(absFileName))\n\toutputFileName := fmt.Sprintf(\"templ_%s.txt\", hex.EncodeToString(hashedFileName[:]))\n\n\troot := os.TempDir()\n\tif os.Getenv(\"TEMPL_DEV_MODE_ROOT\") != \"\" {\n\t\troot = os.Getenv(\"TEMPL_DEV_MODE_ROOT\")\n\t}\n\n\treturn filepath.Join(root, outputFileName)\n}\n\n// normalizePath converts Windows paths to Unix style paths.\nfunc normalizePath(p string) string {\n\tp = strings.ReplaceAll(filepath.Clean(p), `\\`, `/`)\n\tparts := strings.SplitN(p, \":\", 2)\n\tif len(parts) == 2 && len(parts[0]) == 1 {\n\t\tdrive := strings.ToLower(parts[0])\n\t\tp = \"/\" + drive + parts[1]\n\t}\n\treturn p\n}\n\ntype watchState struct {\n\tmodTime time.Time\n\tstrings []string\n}\n\ntype StringLoader struct {\n\twatchModeRoot    string\n\twatchModeRootErr error\n\tcache            map[string]watchState\n\tcacheMutex       sync.Mutex\n}\n\nfunc NewStringLoader(devModeWatchRootPath string) (sl *StringLoader) {\n\tsl = &StringLoader{\n\t\tcache: make(map[string]watchState),\n\t}\n\tif devModeWatchRootPath == \"\" {\n\t\treturn sl\n\t}\n\tresolvedRoot, err := filepath.EvalSymlinks(devModeWatchRootPath)\n\tif err != nil {\n\t\tsl.watchModeRootErr = fmt.Errorf(\"templ: failed to eval symlinks for watch mode root %q: %w\", devModeWatchRootPath, err)\n\t\treturn sl\n\t}\n\tsl.watchModeRoot = resolvedRoot\n\treturn sl\n}\n\nfunc (sl *StringLoader) GetWatchedString(templFilePath string, index int, defaultValue string) (string, error) {\n\tif sl.watchModeRootErr != nil {\n\t\treturn \"\", sl.watchModeRootErr\n\t}\n\tpath, err := filepath.EvalSymlinks(templFilePath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"templ: failed to eval symlinks for %q: %w\", path, err)\n\t}\n\t// If the file is outside the watch mode root, write the string directly.\n\t// If watch mode root is not set, fall back to the previous behaviour to avoid breaking existing setups.\n\tif sl.watchModeRoot != \"\" && !strings.HasPrefix(path, sl.watchModeRoot) {\n\t\treturn defaultValue, nil\n\t}\n\n\ttxtFilePath := GetDevModeTextFileName(path)\n\tliterals, err := sl.getWatchedStrings(txtFilePath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"templ: failed to get watched strings for %q: %w\", path, err)\n\t}\n\tif index > len(literals) {\n\t\treturn \"\", fmt.Errorf(\"templ: failed to find line %d in %s\", index, txtFilePath)\n\t}\n\treturn strconv.Unquote(`\"` + literals[index-1] + `\"`)\n}\n\nfunc (sl *StringLoader) getWatchedStrings(txtFilePath string) ([]string, error) {\n\tsl.cacheMutex.Lock()\n\tdefer sl.cacheMutex.Unlock()\n\n\tstate, cached := sl.cache[txtFilePath]\n\tif !cached {\n\t\treturn sl.cacheStrings(txtFilePath)\n\t}\n\n\tif time.Since(state.modTime) < time.Millisecond*100 {\n\t\treturn state.strings, nil\n\t}\n\n\tinfo, err := os.Stat(txtFilePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to stat %s: %w\", txtFilePath, err)\n\t}\n\n\tif !info.ModTime().After(state.modTime) {\n\t\treturn state.strings, nil\n\t}\n\n\treturn sl.cacheStrings(txtFilePath)\n}\n\nfunc (sl *StringLoader) cacheStrings(txtFilePath string) ([]string, error) {\n\ttxtFile, err := os.Open(txtFilePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to open %s: %w\", txtFilePath, err)\n\t}\n\tdefer func() {\n\t\t_ = txtFile.Close()\n\t}()\n\n\tinfo, err := txtFile.Stat()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to stat %s: %w\", txtFilePath, err)\n\t}\n\n\tall, err := io.ReadAll(txtFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to read %s: %w\", txtFilePath, err)\n\t}\n\n\tliterals := strings.Split(string(all), \"\\n\")\n\tsl.cache[txtFilePath] = watchState{\n\t\tmodTime: info.ModTime(),\n\t\tstrings: literals,\n\t}\n\n\treturn literals, nil\n}\n"
  },
  {
    "path": "runtime/watchmode_test.go",
    "content": "package runtime\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n)\n\nfunc TestGetWatchedString(t *testing.T) {\n\ttests := []struct {\n\t\tname      string\n\t\twatchRoot string\n\t\tfileName  string\n\t\texpected  string\n\t}{\n\t\t{\n\t\t\tname:      \"returns default value when file is outside watch root\",\n\t\t\twatchRoot: \"/root\",\n\t\t\tfileName:  \"/other/fileoutside_templ.go\",\n\t\t\texpected:  \"templ_file_value\",\n\t\t},\n\t\t{\n\t\t\tname:      \"uses cache when file is inside watch root\",\n\t\t\twatchRoot: \"/root\",\n\t\t\tfileName:  \"/root/fileinside_templ.go\",\n\t\t\texpected:  \"txt_file_value\",\n\t\t},\n\t\t{\n\t\t\tname:      \"uses cache when watch root is not set (legacy behaviour)\",\n\t\t\twatchRoot: \"\",\n\t\t\tfileName:  \"/root/file_templ.go\",\n\t\t\texpected:  \"txt_file_value\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Arrange.\n\t\t\ttmpDir := t.TempDir()\n\n\t\t\t// We have to actually make the file because GetWatchedString checks\n\t\t\t// the file's mod time to determine whether to use the cache or read\n\t\t\t// from disk.\n\t\t\ttestFile := filepath.Join(tmpDir, tt.fileName)\n\t\t\tif err := os.MkdirAll(filepath.Dir(testFile), 0755); err != nil {\n\t\t\t\tt.Fatalf(\"failed to create directory: %v\", err)\n\t\t\t}\n\t\t\tif err := os.WriteFile(testFile, []byte(\"test\"), 0644); err != nil {\n\t\t\t\tt.Fatalf(\"failed to write test file: %v\", err)\n\t\t\t}\n\n\t\t\tresolvedPath, err := filepath.EvalSymlinks(testFile)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to eval symlinks for test file: %v\", err)\n\t\t\t}\n\t\t\ttxtFile := GetDevModeTextFileName(resolvedPath)\n\t\t\tif err := os.WriteFile(txtFile, []byte(\"txt_file_value\"), 0644); err != nil {\n\t\t\t\tt.Fatalf(\"failed to write txt file: %v\", err)\n\t\t\t}\n\n\t\t\twatchRootPath := filepath.Join(tmpDir, tt.watchRoot)\n\t\t\tif err := os.MkdirAll(watchRootPath, 0755); err != nil {\n\t\t\t\tt.Fatalf(\"failed to create watch root directory: %v\", err)\n\t\t\t}\n\t\t\tloader := NewStringLoader(watchRootPath)\n\n\t\t\t// Act.\n\t\t\tactual, err := loader.GetWatchedString(testFile, 1, \"templ_file_value\")\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t\t\t}\n\n\t\t\t// Assert.\n\t\t\tif actual != tt.expected {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", tt.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestWatchMode(t *testing.T) {\n\tt.Setenv(\"TEMPL_DEV_MODE_ROOT\", \"/tmp\")\n\n\tt.Run(\"GetDevModeTextFileName respects the TEMPL_DEV_MODE_ROOT environment variable\", func(t *testing.T) {\n\t\texpected := \"/tmp/templ_14a26e43676c091fa17a7f4eccbbf62a44339e3cc6454b9a82c042227a21757f.txt\"\n\t\tactual := GetDevModeTextFileName(\"test.templ\")\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"got %q, want %q\", actual, expected)\n\t\t}\n\t})\n\tt.Run(\"GetDevModeTextFileName replaces _templ.go with .templ\", func(t *testing.T) {\n\t\texpected := \"/tmp/templ_14a26e43676c091fa17a7f4eccbbf62a44339e3cc6454b9a82c042227a21757f.txt\"\n\t\tactual := GetDevModeTextFileName(\"test_templ.go\")\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"got %q, want %q\", actual, expected)\n\t\t}\n\t})\n\tt.Run(\"GetDevModeTextFileName accepts absolute Linux paths\", func(t *testing.T) {\n\t\texpected := \"/tmp/templ_629591f679da14bbba764530c2965c6c8d3a8931f0ba867104c2ec441691ae22.txt\"\n\t\tactual := GetDevModeTextFileName(\"/home/user/test.templ\")\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"got %q, want %q\", actual, expected)\n\t\t}\n\t})\n\tt.Run(\"GetDevModeTextFileName accepts absolute Windows paths, which are normalized to Unix style before hashing\", func(t *testing.T) {\n\t\texpected := \"/tmp/templ_f0321c47222350b736aaa2d18a2b313be03da4fd4ebd80af5745434d8776376f.txt\"\n\t\tactual := GetDevModeTextFileName(`C:\\Windows\\System32\\test.templ`)\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"got %q, want %q\", actual, expected)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "runtime.go",
    "content": "package templ\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"html\"\n\t\"html/template\"\n\t\"io\"\n\t\"net/http\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/a-h/templ/safehtml\"\n)\n\n// Types exposed by all components.\n\n// Component is the interface that all templates implement.\ntype Component interface {\n\t// Render the template.\n\tRender(ctx context.Context, w io.Writer) error\n}\n\n// ComponentFunc converts a function that matches the Component interface's\n// Render method into a Component.\ntype ComponentFunc func(ctx context.Context, w io.Writer) error\n\n// Render the template.\nfunc (cf ComponentFunc) Render(ctx context.Context, w io.Writer) error {\n\treturn cf(ctx, w)\n}\n\n// WithNonce sets a CSP nonce on the context and returns it.\nfunc WithNonce(ctx context.Context, nonce string) context.Context {\n\tctx, v := getContext(ctx)\n\tv.nonce = nonce\n\treturn ctx\n}\n\n// GetNonce returns the CSP nonce value set with WithNonce, or an\n// empty string if none has been set.\nfunc GetNonce(ctx context.Context) (nonce string) {\n\tif ctx == nil {\n\t\treturn \"\"\n\t}\n\t_, v := getContext(ctx)\n\treturn v.nonce\n}\n\nfunc WithChildren(ctx context.Context, children Component) context.Context {\n\tctx, v := getContext(ctx)\n\tv.children = &children\n\treturn ctx\n}\n\nfunc ClearChildren(ctx context.Context) context.Context {\n\t_, v := getContext(ctx)\n\tv.children = nil\n\treturn ctx\n}\n\n// NopComponent is a component that doesn't render anything.\nvar NopComponent = ComponentFunc(func(ctx context.Context, w io.Writer) error { return nil })\n\n// GetChildren from the context.\nfunc GetChildren(ctx context.Context) Component {\n\t_, v := getContext(ctx)\n\tif v.children == nil {\n\t\treturn NopComponent\n\t}\n\treturn *v.children\n}\n\n// EscapeString escapes HTML text within templates.\nfunc EscapeString[T ~string](s T) string {\n\treturn html.EscapeString(string(s))\n}\n\n// Bool attribute value.\nfunc Bool(value bool) bool {\n\treturn value\n}\n\n// Classes for CSS.\n// Supported types are string, ConstantCSSClass, ComponentCSSClass, map[string]bool.\nfunc Classes(classes ...any) CSSClasses {\n\treturn CSSClasses(classes)\n}\n\n// CSSClasses is a slice of CSS classes.\ntype CSSClasses []any\n\n// String returns the names of all CSS classes.\nfunc (classes CSSClasses) String() string {\n\tif len(classes) == 0 {\n\t\treturn \"\"\n\t}\n\tcp := newCSSProcessor()\n\tfor _, v := range classes {\n\t\tcp.Add(v)\n\t}\n\treturn cp.String()\n}\n\nfunc newCSSProcessor() *cssProcessor {\n\treturn &cssProcessor{\n\t\tclassNameToEnabled: make(map[string]bool),\n\t}\n}\n\ntype cssProcessor struct {\n\tclassNameToEnabled map[string]bool\n\torderedNames       []string\n}\n\nfunc (cp *cssProcessor) Add(item any) {\n\tswitch c := item.(type) {\n\tcase []string:\n\t\tfor _, className := range c {\n\t\t\tcp.AddClassName(className, true)\n\t\t}\n\tcase string:\n\t\tcp.AddClassName(c, true)\n\tcase ConstantCSSClass:\n\t\tcp.AddClassName(c.ClassName(), true)\n\tcase ComponentCSSClass:\n\t\tcp.AddClassName(c.ClassName(), true)\n\tcase map[string]bool:\n\t\t// In Go, map keys are iterated in a randomized order.\n\t\t// So the keys in the map must be sorted to produce consistent output.\n\t\tkeys := make([]string, len(c))\n\t\tvar i int\n\t\tfor key := range c {\n\t\t\tkeys[i] = key\n\t\t\ti++\n\t\t}\n\t\tsort.Strings(keys)\n\t\tfor _, className := range keys {\n\t\t\tcp.AddClassName(className, c[className])\n\t\t}\n\tcase []KeyValue[string, bool]:\n\t\tfor _, kv := range c {\n\t\t\tcp.AddClassName(kv.Key, kv.Value)\n\t\t}\n\tcase KeyValue[string, bool]:\n\t\tcp.AddClassName(c.Key, c.Value)\n\tcase []KeyValue[CSSClass, bool]:\n\t\tfor _, kv := range c {\n\t\t\tcp.AddClassName(kv.Key.ClassName(), kv.Value)\n\t\t}\n\tcase KeyValue[CSSClass, bool]:\n\t\tcp.AddClassName(c.Key.ClassName(), c.Value)\n\tcase CSSClasses:\n\t\tfor _, item := range c {\n\t\t\tcp.Add(item)\n\t\t}\n\tcase []CSSClass:\n\t\tfor _, item := range c {\n\t\t\tcp.Add(item)\n\t\t}\n\tcase func() CSSClass:\n\t\tcp.AddClassName(c().ClassName(), true)\n\tdefault:\n\t\tcp.AddClassName(unknownTypeClassName, true)\n\t}\n}\n\nfunc (cp *cssProcessor) AddClassName(className string, enabled bool) {\n\tcp.classNameToEnabled[className] = enabled\n\tcp.orderedNames = append(cp.orderedNames, className)\n}\n\nfunc (cp *cssProcessor) String() string {\n\t// Order the outputs according to how they were input, and remove disabled names.\n\trendered := make(map[string]any, len(cp.classNameToEnabled))\n\tvar names []string\n\tfor _, name := range cp.orderedNames {\n\t\tif enabled := cp.classNameToEnabled[name]; !enabled {\n\t\t\tcontinue\n\t\t}\n\t\tif _, hasBeenRendered := rendered[name]; hasBeenRendered {\n\t\t\tcontinue\n\t\t}\n\t\tnames = append(names, name)\n\t\trendered[name] = struct{}{}\n\t}\n\n\treturn strings.Join(names, \" \")\n}\n\n// KeyValue is a key and value pair.\ntype KeyValue[TKey comparable, TValue any] struct {\n\tKey   TKey   `json:\"name\"`\n\tValue TValue `json:\"value\"`\n}\n\n// KV creates a new key/value pair from the input key and value.\nfunc KV[TKey comparable, TValue any](key TKey, value TValue) KeyValue[TKey, TValue] {\n\treturn KeyValue[TKey, TValue]{\n\t\tKey:   key,\n\t\tValue: value,\n\t}\n}\n\nconst unknownTypeClassName = \"--templ-css-class-unknown-type\"\n\n// Class returns a CSS class name.\n// Deprecated: use a string instead.\nfunc Class(name string) CSSClass {\n\treturn SafeClass(name)\n}\n\n// SafeClass bypasses CSS class name validation.\n// Deprecated: use a string instead.\nfunc SafeClass(name string) CSSClass {\n\treturn ConstantCSSClass(name)\n}\n\n// CSSClass provides a class name.\ntype CSSClass interface {\n\tClassName() string\n}\n\n// ConstantCSSClass is a string constant of a CSS class name.\n// Deprecated: use a string instead.\ntype ConstantCSSClass string\n\n// ClassName of the CSS class.\nfunc (css ConstantCSSClass) ClassName() string {\n\treturn string(css)\n}\n\n// ComponentCSSClass is a templ.CSS\ntype ComponentCSSClass struct {\n\t// ID of the class, will be autogenerated.\n\tID string\n\t// Definition of the CSS.\n\tClass SafeCSS\n}\n\n// ClassName of the CSS class.\nfunc (css ComponentCSSClass) ClassName() string {\n\treturn css.ID\n}\n\n// CSSID calculates an ID.\nfunc CSSID(name string, css string) string {\n\tsum := sha256.Sum256([]byte(css))\n\ths := hex.EncodeToString(sum[:])[0:8] // NOTE: See issue #978. Minimum recommended hs length is 6.\n\t// Benchmarking showed this was fastest, and with fewest allocations (1).\n\t// Using strings.Builder (2 allocs).\n\t// Using fmt.Sprintf (3 allocs).\n\treturn name + \"_\" + hs\n}\n\n// NewCSSMiddleware creates HTTP middleware that renders a global stylesheet of ComponentCSSClass\n// CSS if the request path matches, or updates the HTTP context to ensure that any handlers that\n// use templ.Components skip rendering <style> elements for classes that are included in the global\n// stylesheet. By default, the stylesheet path is /styles/templ.css\nfunc NewCSSMiddleware(next http.Handler, classes ...CSSClass) CSSMiddleware {\n\treturn CSSMiddleware{\n\t\tPath:       \"/styles/templ.css\",\n\t\tCSSHandler: NewCSSHandler(classes...),\n\t\tNext:       next,\n\t}\n}\n\n// CSSMiddleware renders a global stylesheet.\ntype CSSMiddleware struct {\n\tPath       string\n\tCSSHandler CSSHandler\n\tNext       http.Handler\n}\n\nfunc (cssm CSSMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif r.URL.Path == cssm.Path {\n\t\tcssm.CSSHandler.ServeHTTP(w, r)\n\t\treturn\n\t}\n\t// Add registered classes to the context.\n\tctx, v := getContext(r.Context())\n\tfor _, c := range cssm.CSSHandler.Classes {\n\t\tv.addClass(c.ID)\n\t}\n\t// Serve the request. Templ components will use the updated context\n\t// to know to skip rendering <style> elements for any component CSS\n\t// classes that have been included in the global stylesheet.\n\tcssm.Next.ServeHTTP(w, r.WithContext(ctx))\n}\n\n// NewCSSHandler creates a handler that serves a stylesheet containing the CSS of the\n// classes passed in. This is used by the CSSMiddleware to provide global stylesheets\n// for templ components.\nfunc NewCSSHandler(classes ...CSSClass) CSSHandler {\n\tccssc := make([]ComponentCSSClass, 0, len(classes))\n\tfor _, c := range classes {\n\t\tccss, ok := c.(ComponentCSSClass)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tccssc = append(ccssc, ccss)\n\t}\n\treturn CSSHandler{\n\t\tClasses: ccssc,\n\t}\n}\n\n// CSSHandler is a HTTP handler that serves CSS.\ntype CSSHandler struct {\n\tLogger  func(err error)\n\tClasses []ComponentCSSClass\n}\n\nfunc (cssh CSSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tw.Header().Set(\"Content-Type\", \"text/css\")\n\tfor _, c := range cssh.Classes {\n\t\t_, err := w.Write([]byte(c.Class))\n\t\tif err != nil && cssh.Logger != nil {\n\t\t\tcssh.Logger(err)\n\t\t}\n\t}\n}\n\n// RenderCSSItems renders the CSS to the writer, if the items haven't already been rendered.\nfunc RenderCSSItems(ctx context.Context, w io.Writer, classes ...any) (err error) {\n\tif len(classes) == 0 {\n\t\treturn nil\n\t}\n\t_, v := getContext(ctx)\n\tsb := new(strings.Builder)\n\trenderCSSItemsToBuilder(sb, v, classes...)\n\tif sb.Len() == 0 {\n\t\treturn nil\n\t}\n\tif _, err = io.WriteString(w, `<style type=\"text/css\"`); err != nil {\n\t\treturn err\n\t}\n\tif v.nonce != \"\" {\n\t\tif err = writeStrings(w, ` nonce=\"`, EscapeString(v.nonce), `\"`); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn writeStrings(w, `>`, sb.String(), `</style>`)\n}\n\nfunc renderCSSItemsToBuilder(sb *strings.Builder, v *contextValue, classes ...any) {\n\tfor _, c := range classes {\n\t\tswitch ccc := c.(type) {\n\t\tcase ComponentCSSClass:\n\t\t\tif !v.hasClassBeenRendered(ccc.ID) {\n\t\t\t\tsb.WriteString(string(ccc.Class))\n\t\t\t\tv.addClass(ccc.ID)\n\t\t\t}\n\t\tcase KeyValue[ComponentCSSClass, bool]:\n\t\t\tif !ccc.Value {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trenderCSSItemsToBuilder(sb, v, ccc.Key)\n\t\tcase KeyValue[CSSClass, bool]:\n\t\t\tif !ccc.Value {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trenderCSSItemsToBuilder(sb, v, ccc.Key)\n\t\tcase CSSClasses:\n\t\t\trenderCSSItemsToBuilder(sb, v, ccc...)\n\t\tcase []CSSClass:\n\t\t\tfor _, item := range ccc {\n\t\t\t\trenderCSSItemsToBuilder(sb, v, item)\n\t\t\t}\n\t\tcase func() CSSClass:\n\t\t\trenderCSSItemsToBuilder(sb, v, ccc())\n\t\tcase []string:\n\t\t\t// Skip. These are class names, not CSS classes.\n\t\tcase string:\n\t\t\t// Skip. This is a class name, not a CSS class.\n\t\tcase ConstantCSSClass:\n\t\t\t// Skip. This is a class name, not a CSS class.\n\t\tcase CSSClass:\n\t\t\t// Skip. This is a class name, not a CSS class.\n\t\tcase map[string]bool:\n\t\t\t// Skip. These are class names, not CSS classes.\n\t\tcase KeyValue[string, bool]:\n\t\t\t// Skip. These are class names, not CSS classes.\n\t\tcase []KeyValue[string, bool]:\n\t\t\t// Skip. These are class names, not CSS classes.\n\t\tcase KeyValue[ConstantCSSClass, bool]:\n\t\t\t// Skip. These are class names, not CSS classes.\n\t\tcase []KeyValue[ConstantCSSClass, bool]:\n\t\t\t// Skip. These are class names, not CSS classes.\n\t\t}\n\t}\n}\n\n// SafeCSS is CSS that has been sanitized.\ntype SafeCSS string\n\ntype SafeCSSProperty string\n\nvar safeCSSPropertyType = reflect.TypeOf(SafeCSSProperty(\"\"))\n\n// SanitizeCSS sanitizes CSS properties to ensure that they are safe.\nfunc SanitizeCSS[T ~string](property string, value T) SafeCSS {\n\tif reflect.TypeOf(value) == safeCSSPropertyType {\n\t\treturn SafeCSS(safehtml.SanitizeCSSProperty(property) + \":\" + string(value) + \";\")\n\t}\n\tp, v := safehtml.SanitizeCSS(property, string(value))\n\treturn SafeCSS(p + \":\" + v + \";\")\n}\n\ntype Attributer interface {\n\tItems() []KeyValue[string, any]\n}\n\n// Attributes is an alias to map[string]any made for spread attributes.\ntype Attributes map[string]any\n\nvar _ Attributer = Attributes{}\n\n// Returns the items of the attributes map in key sorted order.\nfunc (a Attributes) Items() []KeyValue[string, any] {\n\tvar (\n\t\titems = make([]KeyValue[string, any], len(a))\n\t\ti     int\n\t)\n\tfor k, v := range a {\n\t\titems[i] = KeyValue[string, any]{Key: k, Value: v}\n\t\ti++\n\t}\n\tsort.Slice(items, func(i, j int) bool {\n\t\treturn items[i].Key < items[j].Key\n\t})\n\treturn items\n}\n\n// OrderedAttributes stores attributes in order of insertion.\ntype OrderedAttributes []KeyValue[string, any]\n\nvar _ Attributer = OrderedAttributes{}\n\nfunc (a OrderedAttributes) Items() []KeyValue[string, any] {\n\treturn a\n}\n\nfunc writeStrings(w io.Writer, ss ...string) (err error) {\n\tfor _, s := range ss {\n\t\tif _, err = io.WriteString(w, s); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc RenderAttributes(ctx context.Context, w io.Writer, attributes Attributer) (err error) {\n\tfor _, item := range attributes.Items() {\n\t\tkey := item.Key\n\t\tvalue := item.Value\n\t\tswitch value := value.(type) {\n\t\tcase string:\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key), `=\"`, EscapeString(value), `\"`); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase *string:\n\t\t\tif value == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key), `=\"`, EscapeString(*value), `\"`); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase bool:\n\t\t\tif !value {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase *bool:\n\t\t\tif value == nil || !*value {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase int, int8, int16, int32, int64,\n\t\t\tuint, uint8, uint16, uint32, uint64, uintptr,\n\t\t\tfloat32, float64, complex64, complex128:\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key), `=\"`, EscapeString(fmt.Sprint(value)), `\"`); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase *int, *int8, *int16, *int32, *int64,\n\t\t\t*uint, *uint8, *uint16, *uint32, *uint64, *uintptr,\n\t\t\t*float32, *float64, *complex64, *complex128:\n\t\t\tvalue = ptrValue(value)\n\t\t\tif value == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key), `=\"`, EscapeString(fmt.Sprint(value)), `\"`); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase KeyValue[string, bool]:\n\t\t\tif !value.Value {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key), `=\"`, EscapeString(value.Key), `\"`); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase KeyValue[bool, bool]:\n\t\t\tif !value.Value || !value.Key {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase func() bool:\n\t\t\tif !value() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err = writeStrings(w, ` `, EscapeString(key)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ptrValue(v any) any {\n\tif v == nil {\n\t\treturn nil\n\t}\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Ptr {\n\t\treturn v\n\t}\n\tif rv.IsNil() {\n\t\treturn nil\n\t}\n\treturn rv.Elem().Interface()\n}\n\n// Context.\n\ntype contextKeyType int\n\nconst contextKey = contextKeyType(0)\n\ntype contextValue struct {\n\tss          map[string]struct{}\n\tonceHandles map[*OnceHandle]struct{}\n\tchildren    *Component\n\tnonce       string\n}\n\nfunc (v *contextValue) setHasBeenRendered(h *OnceHandle) {\n\tif v.onceHandles == nil {\n\t\tv.onceHandles = map[*OnceHandle]struct{}{}\n\t}\n\tv.onceHandles[h] = struct{}{}\n}\n\nfunc (v *contextValue) getHasBeenRendered(h *OnceHandle) (ok bool) {\n\tif v.onceHandles == nil {\n\t\tv.onceHandles = map[*OnceHandle]struct{}{}\n\t}\n\t_, ok = v.onceHandles[h]\n\treturn\n}\n\nfunc (v *contextValue) addScript(s string) {\n\tif v.ss == nil {\n\t\tv.ss = map[string]struct{}{}\n\t}\n\tv.ss[\"script_\"+s] = struct{}{}\n}\n\nfunc (v *contextValue) hasScriptBeenRendered(s string) (ok bool) {\n\tif v.ss == nil {\n\t\tv.ss = map[string]struct{}{}\n\t}\n\t_, ok = v.ss[\"script_\"+s]\n\treturn\n}\n\nfunc (v *contextValue) addClass(s string) {\n\tif v.ss == nil {\n\t\tv.ss = map[string]struct{}{}\n\t}\n\tv.ss[\"class_\"+s] = struct{}{}\n}\n\nfunc (v *contextValue) hasClassBeenRendered(s string) (ok bool) {\n\tif v.ss == nil {\n\t\tv.ss = map[string]struct{}{}\n\t}\n\t_, ok = v.ss[\"class_\"+s]\n\treturn\n}\n\n// InitializeContext initializes context used to store internal state used during rendering.\nfunc InitializeContext(ctx context.Context) context.Context {\n\tif _, ok := ctx.Value(contextKey).(*contextValue); ok {\n\t\treturn ctx\n\t}\n\tv := &contextValue{}\n\tctx = context.WithValue(ctx, contextKey, v)\n\treturn ctx\n}\n\nfunc getContext(ctx context.Context) (context.Context, *contextValue) {\n\tv, ok := ctx.Value(contextKey).(*contextValue)\n\tif !ok {\n\t\tctx = InitializeContext(ctx)\n\t\tv = ctx.Value(contextKey).(*contextValue)\n\t}\n\treturn ctx, v\n}\n\nvar bufferPool = sync.Pool{\n\tNew: func() any {\n\t\treturn new(bytes.Buffer)\n\t},\n}\n\nfunc GetBuffer() *bytes.Buffer {\n\treturn bufferPool.Get().(*bytes.Buffer)\n}\n\nfunc ReleaseBuffer(b *bytes.Buffer) {\n\tb.Reset()\n\tbufferPool.Put(b)\n}\n\ntype ints interface {\n\t~int | ~int8 | ~int16 | ~int32 | ~int64\n}\n\ntype uints interface {\n\t~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr\n}\n\ntype floats interface {\n\t~float32 | ~float64\n}\n\ntype complexNumbers interface {\n\t~complex64 | ~complex128\n}\n\ntype stringable interface {\n\tints | uints | floats | complexNumbers | ~string | ~bool\n}\n\n// JoinStringErrs joins an optional list of errors.\nfunc JoinStringErrs[T stringable](s T, errs ...error) (string, error) {\n\treturn fmt.Sprint(s), errors.Join(errs...)\n}\n\n// Error returned during template rendering.\ntype Error struct {\n\tErr error\n\t// FileName of the template file.\n\tFileName string\n\t// Line index of the error.\n\tLine int\n\t// Col index of the error.\n\tCol int\n}\n\nfunc (e Error) Error() string {\n\tif e.FileName == \"\" {\n\t\te.FileName = \"templ\"\n\t}\n\treturn fmt.Sprintf(\"%s: error at line %d, col %d: %v\", e.FileName, e.Line, e.Col, e.Err)\n}\n\nfunc (e Error) Unwrap() error {\n\treturn e.Err\n}\n\n// Raw renders the input HTML to the output without applying HTML escaping.\n//\n// Use of this component presents a security risk - the HTML should come from\n// a trusted source, because it will be included as-is in the output.\nfunc Raw[T ~string](html T, errs ...error) Component {\n\treturn ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\tif err = errors.Join(errs...); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = io.WriteString(w, string(html))\n\t\treturn err\n\t})\n}\n\n// FromGoHTML creates a templ Component from a Go html/template template.\nfunc FromGoHTML(t *template.Template, data any) Component {\n\treturn ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\treturn t.Execute(w, data)\n\t})\n}\n\n// ToGoHTML renders the component to a Go html/template template.HTML string.\nfunc ToGoHTML(ctx context.Context, c Component) (s template.HTML, err error) {\n\tb := GetBuffer()\n\tdefer ReleaseBuffer(b)\n\tif err = c.Render(ctx, b); err != nil {\n\t\treturn\n\t}\n\ts = template.HTML(b.String())\n\treturn\n}\n"
  },
  {
    "path": "runtime_test.go",
    "content": "package templ_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestCSSID(t *testing.T) {\n\tt.Run(\"minimum hash suffix length is 8\", func(t *testing.T) {\n\t\t// See issue #978.\n\t\tname := \"classA\"\n\t\tcss := \"background-color:white;\"\n\t\tactual := len(templ.CSSID(name, css))\n\t\texpected := len(name) + 1 + 8\n\t\tif expected != actual {\n\t\t\tt.Errorf(\"expected length %d, got %d\", expected, actual)\n\t\t}\n\t})\n\tt.Run(\"known hash collisions are avoided\", func(t *testing.T) {\n\t\tname := \"classA\"\n\t\t// Note that the first 4 characters of the hash are the same.\n\t\tcss1 := \"grid-column:1;grid-row:1;\"  // After hash: f781266f\n\t\tcss2 := \"grid-column:13;grid-row:6;\" // After hash: f781f18b\n\t\tid1 := templ.CSSID(name, css1)\n\t\tid2 := templ.CSSID(name, css2)\n\t\tif id1 == id2 {\n\t\t\tt.Errorf(\"hash collision: %s == %s\", id1, id2)\n\t\t}\n\t})\n}\n\nfunc TestCSSHandler(t *testing.T) {\n\ttests := []struct {\n\t\tname             string\n\t\tinput            []templ.CSSClass\n\t\texpectedMIMEType string\n\t\texpectedBody     string\n\t}{\n\t\t{\n\t\t\tname:             \"no classes\",\n\t\t\tinput:            nil,\n\t\t\texpectedMIMEType: \"text/css\",\n\t\t\texpectedBody:     \"\",\n\t\t},\n\t\t{\n\t\t\tname:             \"classes are rendered\",\n\t\t\tinput:            []templ.CSSClass{templ.ComponentCSSClass{ID: \"className\", Class: templ.SafeCSS(\".className{background-color:white;}\")}},\n\t\t\texpectedMIMEType: \"text/css\",\n\t\t\texpectedBody:     \".className{background-color:white;}\",\n\t\t},\n\t\t{\n\t\t\tname: \"classes are rendered\",\n\t\t\tinput: []templ.CSSClass{\n\t\t\t\ttempl.ComponentCSSClass{ID: \"classA\", Class: templ.SafeCSS(\".classA{background-color:white;}\")},\n\t\t\t\ttempl.ComponentCSSClass{ID: \"classB\", Class: templ.SafeCSS(\".classB{background-color:green;}\")},\n\t\t\t},\n\t\t\texpectedMIMEType: \"text/css\",\n\t\t\texpectedBody:     \".classA{background-color:white;}.classB{background-color:green;}\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tw := httptest.NewRecorder()\n\t\t\th := templ.NewCSSHandler(tt.input...)\n\t\t\th.ServeHTTP(w, &http.Request{})\n\t\t\tif diff := cmp.Diff(tt.expectedMIMEType, w.Header().Get(\"Content-Type\")); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expectedBody, w.Body.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCSSMiddleware(t *testing.T) {\n\tpageHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tif _, err := io.WriteString(w, \"Hello, World!\"); err != nil {\n\t\t\tt.Fatalf(\"failed to write string: %v\", err)\n\t\t}\n\t})\n\tc1 := templ.ComponentCSSClass{\n\t\tID:    \"c1\",\n\t\tClass: \".c1{color:red}\",\n\t}\n\tc2 := templ.ComponentCSSClass{\n\t\tID:    \"c2\",\n\t\tClass: \".c2{color:blue}\",\n\t}\n\n\ttests := []struct {\n\t\tname             string\n\t\tinput            *http.Request\n\t\thandler          http.Handler\n\t\texpectedMIMEType string\n\t\texpectedBody     string\n\t}{\n\t\t{\n\t\t\tname:             \"accessing /style/templ.css renders CSS, even if it's empty\",\n\t\t\tinput:            httptest.NewRequest(\"GET\", \"/styles/templ.css\", nil),\n\t\t\thandler:          templ.NewCSSMiddleware(pageHandler),\n\t\t\texpectedMIMEType: \"text/css\",\n\t\t\texpectedBody:     \"\",\n\t\t},\n\t\t{\n\t\t\tname:             \"accessing /style/templ.css renders CSS that includes the classes\",\n\t\t\tinput:            httptest.NewRequest(\"GET\", \"/styles/templ.css\", nil),\n\t\t\thandler:          templ.NewCSSMiddleware(pageHandler, c1, c2),\n\t\t\texpectedMIMEType: \"text/css\",\n\t\t\texpectedBody:     \".c1{color:red}.c2{color:blue}\",\n\t\t},\n\t\t{\n\t\t\tname:             \"the pageHandler is rendered\",\n\t\t\tinput:            httptest.NewRequest(\"GET\", \"/index.html\", nil),\n\t\t\thandler:          templ.NewCSSMiddleware(pageHandler, c1, c2),\n\t\t\texpectedMIMEType: \"text/plain; charset=utf-8\",\n\t\t\texpectedBody:     \"Hello, World!\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tw := httptest.NewRecorder()\n\t\t\ttt.handler.ServeHTTP(w, tt.input)\n\t\t\tif diff := cmp.Diff(tt.expectedMIMEType, w.Header().Get(\"Content-Type\")); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expectedBody, w.Body.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nvar cssInputs = []any{\n\t[]string{\"a\", \"b\"},          // []string\n\t\"c\",                         // string\n\ttempl.ConstantCSSClass(\"d\"), // ConstantCSSClass\n\ttempl.ComponentCSSClass{ID: \"e\", Class: \".e{color:red}\"}, // ComponentCSSClass\n\tmap[string]bool{\"f\": true, \"ff\": false},                  // map[string]bool\n\ttempl.KV(\"g\", true),                                      // KeyValue[string, bool]\n\ttempl.KV(\"gg\", false),                                    // KeyValue[string, bool]\n\t[]templ.KeyValue[string, bool]{\n\t\ttempl.KV(\"h\", true),\n\t\ttempl.KV(\"hh\", false),\n\t}, // []KeyValue[string, bool]\n\ttempl.KV(templ.ConstantCSSClass(\"i\"), true),   // KeyValue[CSSClass, bool]\n\ttempl.KV(templ.ConstantCSSClass(\"ii\"), false), // KeyValue[CSSClass, bool]\n\ttempl.KV(templ.ComponentCSSClass{\n\t\tID:    \"j\",\n\t\tClass: \".j{color:red}\",\n\t}, true), // KeyValue[ComponentCSSClass, bool]\n\ttempl.KV(templ.ComponentCSSClass{\n\t\tID:    \"jj\",\n\t\tClass: \".jj{color:red}\",\n\t}, false), // KeyValue[ComponentCSSClass, bool]\n\ttempl.CSSClasses{templ.ConstantCSSClass(\"k\")},                // CSSClasses\n\tfunc() templ.CSSClass { return templ.ConstantCSSClass(\"l\") }, // func() CSSClass\n\ttempl.CSSClass(templ.ConstantCSSClass(\"m\")),                  // CSSClass\n\tcustomClass{name: \"n\"},                                       // CSSClass\n\t[]templ.CSSClass{customClass{name: \"n\"}},                     // []CSSClass\n\ttempl.KV(templ.ConstantCSSClass(\"o\"), true),                  // KeyValue[ConstantCSSClass, bool]\n\t[]templ.KeyValue[templ.ConstantCSSClass, bool]{\n\t\ttempl.KV(templ.ConstantCSSClass(\"p\"), true),\n\t\ttempl.KV(templ.ConstantCSSClass(\"pp\"), false),\n\t}, // []KeyValue[ConstantCSSClass, bool]\n}\n\ntype customClass struct {\n\tname string\n}\n\nfunc (cc customClass) ClassName() string {\n\treturn cc.name\n}\n\nfunc TestRenderCSS(t *testing.T) {\n\tc1 := templ.ComponentCSSClass{\n\t\tID:    \"c1\",\n\t\tClass: \".c1{color:red}\",\n\t}\n\tc2 := templ.ComponentCSSClass{\n\t\tID:    \"c2\",\n\t\tClass: \".c2{color:blue}\",\n\t}\n\n\ttests := []struct {\n\t\tname     string\n\t\ttoIgnore []any\n\t\ttoRender []any\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"if none are ignored, everything is rendered\",\n\t\t\ttoIgnore: nil,\n\t\t\ttoRender: []any{c1, c2},\n\t\t\texpected: `<style type=\"text/css\">.c1{color:red}.c2{color:blue}</style>`,\n\t\t},\n\t\t{\n\t\t\tname: \"if something outside the expected is ignored, if has no effect\",\n\t\t\ttoIgnore: []any{\n\t\t\t\ttempl.ComponentCSSClass{\n\t\t\t\t\tID:    \"c3\",\n\t\t\t\t\tClass: templ.SafeCSS(\".c3{color:yellow}\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\ttoRender: []any{c1, c2},\n\t\t\texpected: `<style type=\"text/css\">.c1{color:red}.c2{color:blue}</style>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"if one is ignored, it's not rendered\",\n\t\t\ttoIgnore: []any{c1},\n\t\t\ttoRender: []any{c1, c2},\n\t\t\texpected: `<style type=\"text/css\">.c2{color:blue}</style>`,\n\t\t},\n\t\t{\n\t\t\tname: \"if all are ignored, not even style tags are rendered\",\n\t\t\ttoIgnore: []any{\n\t\t\t\tc1,\n\t\t\t\tc2,\n\t\t\t\ttempl.ComponentCSSClass{\n\t\t\t\t\tID:    \"c3\",\n\t\t\t\t\tClass: templ.SafeCSS(\".c3{color:yellow}\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\ttoRender: []any{c1, c2},\n\t\t\texpected: ``,\n\t\t},\n\t\t{\n\t\t\tname:     \"CSS classes are rendered\",\n\t\t\ttoIgnore: nil,\n\t\t\ttoRender: cssInputs,\n\t\t\texpected: `<style type=\"text/css\">.e{color:red}.j{color:red}</style>`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\t\t\tb := new(bytes.Buffer)\n\n\t\t\t// Render twice, reusing the same context so that there's a memory of which classes have been rendered.\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\terr := templ.RenderCSSItems(ctx, b, tt.toIgnore...)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to render initial CSS: %v\", err)\n\t\t\t}\n\n\t\t\t// Now render again to check that only the expected classes were rendered.\n\t\t\tb.Reset()\n\t\t\terr = templ.RenderCSSItems(ctx, b, tt.toRender...)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to render CSS: %v\", err)\n\t\t\t}\n\n\t\t\tif diff := cmp.Diff(tt.expected, b.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestRenderCSSItemsWithNonce(t *testing.T) {\n\tctx := templ.WithNonce(context.Background(), \"testnonce\")\n\tb := new(bytes.Buffer)\n\tc := templ.ComponentCSSClass{\n\t\tID:    \"c1\",\n\t\tClass: \".c1{color:red}\",\n\t}\n\terr := templ.RenderCSSItems(ctx, b, c)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to render CSS: %v\", err)\n\t}\n\tactual := b.String()\n\t// Should include nonce attribute on <style> tag.\n\texpected := `<style type=\"text/css\" nonce=\"testnonce\">.c1{color:red}</style>`\n\tif actual != expected {\n\t\tt.Errorf(\"expected %q, got %q\", expected, actual)\n\t}\n}\n\nfunc TestClassesFunction(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []any\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"constants are allowed\",\n\t\t\tinput:    []any{\"a\", \"b\", \"c\", \"</style>\"},\n\t\t\texpected: \"a b c </style>\",\n\t\t},\n\t\t{\n\t\t\tname:     \"legacy CSS types are supported\",\n\t\t\tinput:    []any{\"a\", templ.SafeClass(\"b\"), templ.Class(\"c\")},\n\t\t\texpected: \"a b c\",\n\t\t},\n\t\t{\n\t\t\tname: \"CSS components are included in the output\",\n\t\t\tinput: []any{\n\t\t\t\ttempl.ComponentCSSClass{ID: \"classA\", Class: templ.SafeCSS(\".classA{background-color:white;}\")},\n\t\t\t\ttempl.ComponentCSSClass{ID: \"classB\", Class: templ.SafeCSS(\".classB{background-color:green;}\")},\n\t\t\t\t\"c\",\n\t\t\t},\n\t\t\texpected: \"classA classB c\",\n\t\t},\n\t\t{\n\t\t\tname: \"optional classes can be applied with expressions\",\n\t\t\tinput: []any{\n\t\t\t\t\"a\",\n\t\t\t\ttempl.ComponentCSSClass{ID: \"classA\", Class: templ.SafeCSS(\".classA{background-color:white;}\")},\n\t\t\t\ttempl.ComponentCSSClass{ID: \"classB\", Class: templ.SafeCSS(\".classB{background-color:green;}\")},\n\t\t\t\t\"c\",\n\t\t\t\tmap[string]bool{\n\t\t\t\t\t\"a\":      false,\n\t\t\t\t\t\"classA\": false,\n\t\t\t\t\t\"classB\": false,\n\t\t\t\t\t\"c\":      true,\n\t\t\t\t\t\"d\":      false,\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"c\",\n\t\t},\n\t\t{\n\t\t\tname: \"unknown types for classes get rendered as --templ-css-class-unknown-type\",\n\t\t\tinput: []any{\n\t\t\t\t123,\n\t\t\t\tmap[string]string{\"test\": \"no\"},\n\t\t\t\tfalse,\n\t\t\t\t\"c\",\n\t\t\t},\n\t\t\texpected: \"--templ-css-class-unknown-type c\",\n\t\t},\n\t\t{\n\t\t\tname: \"string arrays are supported\",\n\t\t\tinput: []any{\n\t\t\t\t[]string{\"a\", \"b\", \"c\", \"</style>\"},\n\t\t\t\t\"d\",\n\t\t\t},\n\t\t\texpected: \"a b c </style> d\",\n\t\t},\n\t\t{\n\t\t\tname: \"strings are broken up\",\n\t\t\tinput: []any{\n\t\t\t\t\"a </style>\",\n\t\t\t},\n\t\t\texpected: \"a </style>\",\n\t\t},\n\t\t{\n\t\t\tname: \"if a templ.CSSClasses is passed in, the nested CSSClasses are extracted\",\n\t\t\tinput: []any{\n\t\t\t\ttempl.Classes(\n\t\t\t\t\t\"a\",\n\t\t\t\t\ttempl.SafeClass(\"b\"),\n\t\t\t\t\ttempl.Class(\"c\"),\n\t\t\t\t\ttempl.ComponentCSSClass{\n\t\t\t\t\t\tID:    \"d\",\n\t\t\t\t\t\tClass: \"{}\",\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t\texpected: \"a b c d\",\n\t\t},\n\t\t{\n\t\t\tname: \"kv types can be used to show or hide classes\",\n\t\t\tinput: []any{\n\t\t\t\t\"a\",\n\t\t\t\ttempl.KV(\"b\", true),\n\t\t\t\t\"c\",\n\t\t\t\ttempl.KV(\"c\", false),\n\t\t\t\ttempl.KV(templ.SafeClass(\"d\"), true),\n\t\t\t\ttempl.KV(templ.SafeClass(\"e\"), false),\n\t\t\t},\n\t\t\texpected: \"a b d\",\n\t\t},\n\t\t{\n\t\t\tname: \"an array of KV types can be used to show or hide classes\",\n\t\t\tinput: []any{\n\t\t\t\t\"a\",\n\t\t\t\t\"c\",\n\t\t\t\t[]templ.KeyValue[string, bool]{\n\t\t\t\t\ttempl.KV(\"b\", true),\n\t\t\t\t\ttempl.KV(\"c\", false),\n\t\t\t\t\t{\"d\", true},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"a b d\",\n\t\t},\n\t\t{\n\t\t\tname: \"the brackets on component CSS function calls can be elided\",\n\t\t\tinput: []any{\n\t\t\t\tfunc() templ.CSSClass {\n\t\t\t\t\treturn templ.ComponentCSSClass{\n\t\t\t\t\t\tID:    \"a\",\n\t\t\t\t\t\tClass: \"\",\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: \"a\",\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tactual := templ.Classes(test.input...).String()\n\t\t\tif actual != test.expected {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", test.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n\ntype baseError struct {\n\tValue int\n}\n\nfunc (baseError) Error() string { return \"base error\" }\n\ntype nonMatchedError struct{}\n\nfunc (nonMatchedError) Error() string { return \"non matched error\" }\n\nfunc TestErrorWrapping(t *testing.T) {\n\tbaseErr := baseError{\n\t\tValue: 1,\n\t}\n\twrappedErr := templ.Error{Err: baseErr, Line: 1, Col: 2}\n\tt.Run(\"errors.Is() returns true for the base error\", func(t *testing.T) {\n\t\tif !errors.Is(wrappedErr, baseErr) {\n\t\t\tt.Error(\"errors.Is() returned false for the base error\")\n\t\t}\n\t})\n\tt.Run(\"errors.Is() returns false for a different error\", func(t *testing.T) {\n\t\tif errors.Is(wrappedErr, errors.New(\"different error\")) {\n\t\t\tt.Error(\"errors.Is() returned true for a different error\")\n\t\t}\n\t})\n\tt.Run(\"errors.As() returns true for the base error\", func(t *testing.T) {\n\t\tvar err baseError\n\t\tif !errors.As(wrappedErr, &err) {\n\t\t\tt.Error(\"errors.As() returned false for the base error\")\n\t\t}\n\t\tif err.Value != 1 {\n\t\t\tt.Errorf(\"errors.As() returned a different value: %v\", err.Value)\n\t\t}\n\t})\n\tt.Run(\"errors.As() returns false for a different error\", func(t *testing.T) {\n\t\tvar err nonMatchedError\n\t\tif errors.As(wrappedErr, &err) {\n\t\t\tt.Error(\"errors.As() returned true for a different error\")\n\t\t}\n\t})\n}\n\nfunc TestRawComponent(t *testing.T) {\n\ttests := []struct {\n\t\tname        string\n\t\tinput       templ.Component\n\t\texpected    string\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname:     \"Raw content is not escaped\",\n\t\t\tinput:    templ.Raw(\"<div>Test &</div>\"),\n\t\t\texpected: `<div>Test &</div>`,\n\t\t},\n\t\t{\n\t\t\tname:        \"Raw will return errors first\",\n\t\t\tinput:       templ.Raw(\"\", nil, errors.New(\"test error\")),\n\t\t\texpected:    `<div>Test &</div>`,\n\t\t\texpectedErr: errors.New(\"test error\"),\n\t\t},\n\t\t{\n\t\t\tname:     \"Strings marked as safe are rendered without escaping\",\n\t\t\tinput:    templ.Raw(template.HTML(\"<div>\")),\n\t\t\texpected: `<div>`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tb := new(bytes.Buffer)\n\t\t\terr := tt.input.Render(context.Background(), b)\n\t\t\tif tt.expectedErr != nil {\n\t\t\t\texpected := tt.expectedErr.Error()\n\t\t\t\tactual := fmt.Sprintf(\"%v\", err)\n\t\t\t\tif actual != expected {\n\t\t\t\t\tt.Errorf(\"expected error %q, got %q\", expected, actual)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to render content: %v\", err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.expected, b.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n\tt.Run(\"Raw does not require allocations\", func(t *testing.T) {\n\t\tactualAllocs := testing.AllocsPerRun(4, func() {\n\t\t\tc := templ.Raw(\"<div>\")\n\t\t\tif c == nil {\n\t\t\t\tt.Fatalf(\"unexpected nil value\")\n\t\t\t}\n\t\t})\n\t\tif actualAllocs > 0 {\n\t\t\tt.Errorf(\"expected no allocs, got %v\", actualAllocs)\n\t\t}\n\t})\n}\n\nvar goTemplate = template.Must(template.New(\"example\").Parse(\"<div>{{ . }}</div>\"))\n\nfunc TestGoHTMLComponents(t *testing.T) {\n\tt.Run(\"Go templates can be rendered as templ components\", func(t *testing.T) {\n\t\tb := new(bytes.Buffer)\n\t\terr := templ.FromGoHTML(goTemplate, \"Test &\").Render(context.Background(), b)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to render content: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(\"<div>Test &amp;</div>\", b.String()); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"templ components can be rendered in Go templates\", func(t *testing.T) {\n\t\tb := new(bytes.Buffer)\n\t\tc := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\t\t_, err = io.WriteString(w, \"<div>Unsanitized &</div>\")\n\t\t\treturn err\n\t\t})\n\t\th, err := templ.ToGoHTML(context.Background(), c)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to convert to Go HTML: %v\", err)\n\t\t}\n\t\tif err = goTemplate.Execute(b, h); err != nil {\n\t\t\tt.Fatalf(\"failed to render content: %v\", err)\n\t\t}\n\t\tif diff := cmp.Diff(\"<div><div>Unsanitized &</div></div>\", b.String()); diff != \"\" {\n\t\t\tt.Error(diff)\n\t\t}\n\t})\n\tt.Run(\"errors in ToGoHTML are returned\", func(t *testing.T) {\n\t\texpectedErr := errors.New(\"test error\")\n\t\tc := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\t\treturn expectedErr\n\t\t})\n\t\t_, err := templ.ToGoHTML(context.Background(), c)\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"expected error, got nil\")\n\t\t}\n\t\tif err != expectedErr {\n\t\t\tt.Fatalf(\"expected error %q, got %q\", expectedErr, err)\n\t\t}\n\t})\n\tt.Run(\"FromGoHTML does not require allocations\", func(t *testing.T) {\n\t\tactualAllocs := testing.AllocsPerRun(4, func() {\n\t\t\tc := templ.FromGoHTML(goTemplate, \"test &\")\n\t\t\tif c == nil {\n\t\t\t\tt.Fatalf(\"unexpected nil value\")\n\t\t\t}\n\t\t})\n\t\tif actualAllocs > 0 {\n\t\t\tt.Errorf(\"expected no allocs, got %v\", actualAllocs)\n\t\t}\n\t})\n\tt.Run(\"ToGoHTML requires one allocation\", func(t *testing.T) {\n\t\texpected := \"<div>Unsanitized &</div>\"\n\t\tc := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {\n\t\t\t_, err = io.WriteString(w, expected)\n\t\t\treturn err\n\t\t})\n\t\tactualAllocs := testing.AllocsPerRun(4, func() {\n\t\t\th, err := templ.ToGoHTML(context.Background(), c)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to convert to Go HTML: %v\", err)\n\t\t\t}\n\t\t\tif h != template.HTML(expected) {\n\t\t\t\tt.Fatalf(\"unexpected value\")\n\t\t\t}\n\t\t})\n\t\tif actualAllocs > 1 {\n\t\t\tt.Errorf(\"expected 1 alloc, got %v\", actualAllocs)\n\t\t}\n\t})\n}\n\nfunc TestNonce(t *testing.T) {\n\tctx := context.Background()\n\tt.Run(\"returns empty string if not set\", func(t *testing.T) {\n\t\tactual := templ.GetNonce(ctx)\n\t\tif actual != \"\" {\n\t\t\tt.Errorf(\"expected empty string got %q\", actual)\n\t\t}\n\t})\n\tt.Run(\"returns value if one has been set\", func(t *testing.T) {\n\t\texpected := \"abc123\"\n\t\tctx := templ.WithNonce(context.Background(), expected)\n\t\tactual := templ.GetNonce(ctx)\n\t\tif actual != expected {\n\t\t\tt.Errorf(\"expected %q got %q\", expected, actual)\n\t\t}\n\t})\n}\n\nfunc TestRenderAttributes(t *testing.T) {\n\ttests := []struct {\n\t\tname       string\n\t\tattributes templ.Attributes\n\t\texpected   string\n\t}{\n\t\t{\n\t\t\tname: \"string attributes are rendered\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"class\": \"test-class\",\n\t\t\t\t\"id\":    \"test-id\",\n\t\t\t},\n\t\t\texpected: ` class=\"test-class\" id=\"test-id\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"integer types are rendered as strings\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"int\":   42,\n\t\t\t\t\"int8\":  int8(8),\n\t\t\t\t\"int16\": int16(16),\n\t\t\t\t\"int32\": int32(32),\n\t\t\t\t\"int64\": int64(64),\n\t\t\t},\n\t\t\texpected: ` int=\"42\" int16=\"16\" int32=\"32\" int64=\"64\" int8=\"8\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"unsigned integer types are rendered as strings\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"uint\":    uint(42),\n\t\t\t\t\"uint8\":   uint8(8),\n\t\t\t\t\"uint16\":  uint16(16),\n\t\t\t\t\"uint32\":  uint32(32),\n\t\t\t\t\"uint64\":  uint64(64),\n\t\t\t\t\"uintptr\": uintptr(100),\n\t\t\t},\n\t\t\texpected: ` uint=\"42\" uint16=\"16\" uint32=\"32\" uint64=\"64\" uint8=\"8\" uintptr=\"100\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"float types are rendered as strings\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"float32\": float32(3.14),\n\t\t\t\t\"float64\": float64(2.718),\n\t\t\t},\n\t\t\texpected: ` float32=\"3.14\" float64=\"2.718\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"complex types are rendered as strings\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"complex64\":  complex64(1 + 2i),\n\t\t\t\t\"complex128\": complex128(3 + 4i),\n\t\t\t},\n\t\t\texpected: ` complex128=\"(3+4i)\" complex64=\"(1+2i)\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"boolean attributes are rendered correctly\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"checked\":  true,\n\t\t\t\t\"disabled\": false,\n\t\t\t},\n\t\t\texpected: ` checked`,\n\t\t},\n\t\t{\n\t\t\tname: \"mixed types are rendered correctly\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"class\":  \"button\",\n\t\t\t\t\"value\":  42,\n\t\t\t\t\"width\":  float64(100.5),\n\t\t\t\t\"hidden\": false,\n\t\t\t\t\"active\": true,\n\t\t\t},\n\t\t\texpected: ` active class=\"button\" value=\"42\" width=\"100.5\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"nil pointer attributes are not rendered\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"optional\": (*string)(nil),\n\t\t\t\t\"visible\":  (*bool)(nil),\n\t\t\t},\n\t\t\texpected: ``,\n\t\t},\n\t\t{\n\t\t\tname: \"non-nil pointer attributes are rendered\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"title\":   ptr(\"test title\"),\n\t\t\t\t\"enabled\": ptr(true),\n\t\t\t},\n\t\t\texpected: ` enabled title=\"test title\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"numeric pointer types are rendered as strings\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"int-ptr\":        ptr(42),\n\t\t\t\t\"int8-ptr\":       ptr(int8(8)),\n\t\t\t\t\"int16-ptr\":      ptr(int16(16)),\n\t\t\t\t\"int32-ptr\":      ptr(int32(32)),\n\t\t\t\t\"int64-ptr\":      ptr(int64(64)),\n\t\t\t\t\"uint-ptr\":       ptr(uint(42)),\n\t\t\t\t\"uint8-ptr\":      ptr(uint8(8)),\n\t\t\t\t\"uint16-ptr\":     ptr(uint16(16)),\n\t\t\t\t\"uint32-ptr\":     ptr(uint32(32)),\n\t\t\t\t\"uint64-ptr\":     ptr(uint64(64)),\n\t\t\t\t\"uintptr-ptr\":    ptr(uintptr(100)),\n\t\t\t\t\"float32-ptr\":    ptr(float32(3.14)),\n\t\t\t\t\"float64-ptr\":    ptr(float64(2.718)),\n\t\t\t\t\"complex64-ptr\":  ptr(complex64(1 + 2i)),\n\t\t\t\t\"complex128-ptr\": ptr(complex128(3 + 4i)),\n\t\t\t},\n\t\t\texpected: ` complex128-ptr=\"(3+4i)\" complex64-ptr=\"(1+2i)\" float32-ptr=\"3.14\" float64-ptr=\"2.718\" int-ptr=\"42\" int16-ptr=\"16\" int32-ptr=\"32\" int64-ptr=\"64\" int8-ptr=\"8\" uint-ptr=\"42\" uint16-ptr=\"16\" uint32-ptr=\"32\" uint64-ptr=\"64\" uint8-ptr=\"8\" uintptr-ptr=\"100\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"nil numeric pointer attributes are not rendered\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"int-ptr\":       (*int)(nil),\n\t\t\t\t\"float32-ptr\":   (*float32)(nil),\n\t\t\t\t\"complex64-ptr\": (*complex64)(nil),\n\t\t\t},\n\t\t\texpected: ``,\n\t\t},\n\t\t{\n\t\t\tname: \"KeyValue[string, bool] attributes are rendered correctly\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"data-value\":  templ.KV(\"test-string\", true),\n\t\t\t\t\"data-hidden\": templ.KV(\"ignored\", false),\n\t\t\t},\n\t\t\texpected: ` data-value=\"test-string\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"KeyValue[bool, bool] attributes are rendered correctly\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"checked\":  templ.KV(true, true),\n\t\t\t\t\"disabled\": templ.KV(false, true),\n\t\t\t\t\"hidden\":   templ.KV(true, false),\n\t\t\t},\n\t\t\texpected: ` checked`,\n\t\t},\n\t\t{\n\t\t\tname: \"function bool attributes are rendered correctly\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"enabled\": func() bool { return true },\n\t\t\t\t\"hidden\":  func() bool { return false },\n\t\t\t},\n\t\t\texpected: ` enabled`,\n\t\t},\n\t\t{\n\t\t\tname: \"mixed KeyValue and function attributes\",\n\t\t\tattributes: templ.Attributes{\n\t\t\t\t\"data-name\": templ.KV(\"value\", true),\n\t\t\t\t\"active\":    templ.KV(true, true),\n\t\t\t\t\"dynamic\":   func() bool { return true },\n\t\t\t\t\"ignored\":   templ.KV(\"ignored\", false),\n\t\t\t},\n\t\t\texpected: ` active data-name=\"value\" dynamic`,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar buf bytes.Buffer\n\t\t\terr := templ.RenderAttributes(context.Background(), &buf, tt.attributes)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"RenderAttributes failed: %v\", err)\n\t\t\t}\n\n\t\t\tactual := buf.String()\n\t\t\tif actual != tt.expected {\n\t\t\t\tt.Errorf(\"expected %q, got %q\", tt.expected, actual)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc ptr[T any](x T) *T {\n\treturn &x\n}\n"
  },
  {
    "path": "safehtml/style.go",
    "content": "// Adapted from https://raw.githubusercontent.com/google/safehtml/3c4cd5b5d8c9a6c5882fba099979e9f50b65c876/style.go\n\n// Copyright (c) 2017 The Go Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file or at\n// https://developers.google.com/open-source/licenses/bsd\n\npackage safehtml\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// SanitizeCSS attempts to sanitize CSS properties.\nfunc SanitizeCSS(property, value string) (string, string) {\n\tproperty = SanitizeCSSProperty(property)\n\tif property == InnocuousPropertyName {\n\t\treturn InnocuousPropertyName, InnocuousPropertyValue\n\t}\n\treturn property, SanitizeCSSValue(property, value)\n}\n\nfunc SanitizeCSSValue(property, value string) string {\n\tif sanitizer, ok := cssPropertyNameToValueSanitizer[property]; ok {\n\t\treturn sanitizer(value)\n\t}\n\treturn sanitizeRegular(value)\n}\n\nfunc SanitizeCSSProperty(property string) string {\n\tif !identifierPattern.MatchString(property) {\n\t\treturn InnocuousPropertyName\n\t}\n\treturn strings.ToLower(property)\n}\n\n// identifierPattern matches a subset of valid <ident-token> values defined in\n// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram. This pattern matches all generic family name\n// keywords defined in https://drafts.csswg.org/css-fonts-3/#family-name-value.\nvar identifierPattern = regexp.MustCompile(`^[-a-zA-Z]+$`)\n\nvar cssPropertyNameToValueSanitizer = map[string]func(string) string{\n\t\"background-image\":    sanitizeBackgroundImage,\n\t\"font-family\":         sanitizeFontFamily,\n\t\"display\":             sanitizeEnum,\n\t\"background-color\":    sanitizeRegular,\n\t\"background-position\": sanitizeRegular,\n\t\"background-repeat\":   sanitizeRegular,\n\t\"background-size\":     sanitizeRegular,\n\t\"color\":               sanitizeRegular,\n\t\"height\":              sanitizeRegular,\n\t\"width\":               sanitizeRegular,\n\t\"left\":                sanitizeRegular,\n\t\"right\":               sanitizeRegular,\n\t\"top\":                 sanitizeRegular,\n\t\"bottom\":              sanitizeRegular,\n\t\"font-weight\":         sanitizeRegular,\n\t\"padding\":             sanitizeRegular,\n\t\"z-index\":             sanitizeRegular,\n}\n\nvar validURLPrefixes = []string{\n\t`url(\"`,\n\t`url('`,\n\t`url(`,\n}\n\nvar validURLSuffixes = []string{\n\t`\")`,\n\t`')`,\n\t`)`,\n}\n\nfunc sanitizeBackgroundImage(v string) string {\n\t// Check for <> as per https://github.com/google/safehtml/blob/be23134998433fcf0135dda53593fc8f8bf4df7c/style.go#L87C2-L89C3\n\tif strings.ContainsAny(v, \"<>\") {\n\t\treturn InnocuousPropertyValue\n\t}\n\tfor _, u := range strings.Split(v, \",\") {\n\t\tu = strings.TrimSpace(u)\n\t\tvar found bool\n\t\tfor i, prefix := range validURLPrefixes {\n\t\t\tif strings.HasPrefix(u, prefix) && strings.HasSuffix(u, validURLSuffixes[i]) {\n\t\t\t\tfound = true\n\t\t\t\tu = strings.TrimPrefix(u, validURLPrefixes[i])\n\t\t\t\tu = strings.TrimSuffix(u, validURLSuffixes[i])\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found || !urlIsSafe(u) {\n\t\t\treturn InnocuousPropertyValue\n\t\t}\n\t}\n\treturn v\n}\n\nfunc urlIsSafe(s string) bool {\n\tu, err := url.Parse(s)\n\tif err != nil {\n\t\treturn false\n\t}\n\tif u.IsAbs() {\n\t\tif strings.EqualFold(u.Scheme, \"http\") || strings.EqualFold(u.Scheme, \"https\") || strings.EqualFold(u.Scheme, \"mailto\") {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n\nvar genericFontFamilyName = regexp.MustCompile(`^[a-zA-Z][- a-zA-Z]+$`)\n\nfunc sanitizeFontFamily(s string) string {\n\tfor _, f := range strings.Split(s, \",\") {\n\t\tf = strings.TrimSpace(f)\n\t\tif strings.HasPrefix(f, `\"`) {\n\t\t\tif !strings.HasSuffix(f, `\"`) {\n\t\t\t\treturn InnocuousPropertyValue\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif !genericFontFamilyName.MatchString(f) {\n\t\t\treturn InnocuousPropertyValue\n\t\t}\n\t}\n\treturn s\n}\n\nfunc sanitizeEnum(s string) string {\n\tif !safeEnumPropertyValuePattern.MatchString(s) {\n\t\treturn InnocuousPropertyValue\n\t}\n\treturn s\n}\n\nfunc sanitizeRegular(s string) string {\n\tif !safeRegularPropertyValuePattern.MatchString(s) {\n\t\treturn InnocuousPropertyValue\n\t}\n\treturn s\n}\n\n// InnocuousPropertyName is an innocuous property generated by a sanitizer when its input is unsafe.\nconst InnocuousPropertyName = \"zTemplUnsafeCSSPropertyName\"\n\n// InnocuousPropertyValue is an innocuous property generated by a sanitizer when its input is unsafe.\nconst InnocuousPropertyValue = \"zTemplUnsafeCSSPropertyValue\"\n\n// safeRegularPropertyValuePattern matches strings that are safe to use as property values.\n// Specifically, it matches string where every '*' or '/' is followed by end-of-text or a safe rune\n// (i.e. alphanumerics or runes in the set [+-.!#%_ \\t]). This regex ensures that the following\n// are disallowed:\n//   - \"/*\" and \"*/\", which are CSS comment markers.\n//   - \"//\", even though this is not a comment marker in the CSS specification. Disallowing\n//     this string minimizes the chance that browser peculiarities or parsing bugs will allow\n//     sanitization to be bypassed.\n//   - '(' and ')', which can be used to call functions.\n//   - ',', since it can be used to inject extra values into a property.\n//   - Runes which could be matched on CSS error recovery of a previously malformed token, such as '@'\n//     and ':'. See http://www.w3.org/TR/css3-syntax/#error-handling.\nvar safeRegularPropertyValuePattern = regexp.MustCompile(`^(?:[*/]?(?:[0-9a-zA-Z+-.!#%_ \\t]|$))*$`)\n\n// safeEnumPropertyValuePattern matches strings that are safe to use as enumerated property values.\n// Specifically, it matches strings that contain only alphabetic and '-' runes.\nvar safeEnumPropertyValuePattern = regexp.MustCompile(`^[a-zA-Z-]*$`)\n\n// SanitizeStyleValue escapes s so that it is safe to put between \"\" to form a CSS <string-token>.\n// See syntax at https://www.w3.org/TR/css-syntax-3/#string-token-diagram.\n//\n// On top of the escape sequences required in <string-token>, this function also escapes\n// control runes to minimize the risk of these runes triggering browser-specific bugs.\n// Taken from cssEscapeString in safehtml package.\nfunc SanitizeStyleValue(s string) string {\n\tvar b bytes.Buffer\n\tb.Grow(len(s))\n\tfor _, c := range s {\n\t\tswitch {\n\t\tcase c == '\\u0000':\n\t\t\t// Replace the NULL byte according to https://www.w3.org/TR/css-syntax-3/#input-preprocessing.\n\t\t\t// We take this extra precaution in case the user agent fails to handle NULL properly.\n\t\t\tb.WriteString(\"\\uFFFD\")\n\t\tcase c == '<', // Prevents breaking out of a style element with `</style>`. Escape this in case the Style user forgets to.\n\t\t\tc == '\"', c == '\\\\', // Must be CSS-escaped in <string-token>. U+000A line feed is handled in the next case.\n\t\t\tc <= '\\u001F', c == '\\u007F', // C0 control codes\n\t\t\tc >= '\\u0080' && c <= '\\u009F', // C1 control codes\n\t\t\tc == '\\u2028', c == '\\u2029':   // Unicode newline characters\n\t\t\t// See CSS escape sequence syntax at https://www.w3.org/TR/css-syntax-3/#escape-diagram.\n\t\t\tfmt.Fprintf(&b, \"\\\\%06X\", c)\n\t\tdefault:\n\t\t\tb.WriteRune(c)\n\t\t}\n\t}\n\treturn b.String()\n}\n"
  },
  {
    "path": "safehtml/style_test.go",
    "content": "package safehtml\n\nimport \"testing\"\n\nfunc TestSanitizeCSS(t *testing.T) {\n\ttests := []struct {\n\t\tname             string\n\t\tinputProperty    string\n\t\texpectedProperty string\n\t\tinputValue       string\n\t\texpectedValue    string\n\t}{\n\t\t{\n\t\t\tname:             \"directions are allowed\",\n\t\t\tinputProperty:    \"dir\",\n\t\t\texpectedProperty: \"dir\",\n\t\t\tinputValue:       \"ltr\",\n\t\t\texpectedValue:    \"ltr\",\n\t\t},\n\t\t{\n\t\t\tname:             \"border-left allowed\",\n\t\t\tinputProperty:    \"border-left\",\n\t\t\texpectedProperty: \"border-left\",\n\t\t\tinputValue:       \"0\",\n\t\t\texpectedValue:    \"0\",\n\t\t},\n\t\t{\n\t\t\tname:             \"border can contain multiple values\",\n\t\t\tinputProperty:    \"border\",\n\t\t\texpectedProperty: \"border\",\n\t\t\tinputValue:       `1 1 1 1`,\n\t\t\texpectedValue:    `1 1 1 1`,\n\t\t},\n\t\t{\n\t\t\tname:             \"properties are case corrected\",\n\t\t\tinputProperty:    \"Border\",\n\t\t\texpectedProperty: \"border\",\n\t\t\tinputValue:       `1 1 1 1`,\n\t\t\texpectedValue:    `1 1 1 1`,\n\t\t},\n\t\t{\n\t\t\tname:             \"expressions are not allowed\",\n\t\t\tinputProperty:    \"width\",\n\t\t\texpectedProperty: \"width\",\n\t\t\tinputValue:       `expression(alert(1337))`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"font-family standard values are allowed\",\n\t\t\tinputProperty:    \"font-family\",\n\t\t\texpectedProperty: \"font-family\",\n\t\t\tinputValue:       `sans-serif`,\n\t\t\texpectedValue:    `sans-serif`,\n\t\t},\n\t\t{\n\t\t\tname:             \"font-family values with spaces are allowed\",\n\t\t\tinputProperty:    \"font-family\",\n\t\t\texpectedProperty: \"font-family\",\n\t\t\tinputValue:       `Akzidenz Grotesk`,\n\t\t\texpectedValue:    `Akzidenz Grotesk`,\n\t\t},\n\t\t{\n\t\t\tname:             \"font-family multiple standard values are allowed\",\n\t\t\tinputProperty:    \"font-family\",\n\t\t\texpectedProperty: \"font-family\",\n\t\t\tinputValue:       `sans-serif, monospaced`,\n\t\t\texpectedValue:    `sans-serif, monospaced`,\n\t\t},\n\t\t{\n\t\t\tname:             \"font-family multiple quoted and non-quoted values are allowed\",\n\t\t\tinputProperty:    \"font-family\",\n\t\t\texpectedProperty: \"font-family\",\n\t\t\tinputValue:       `\"Georgia\", monospaced, sans-serif`,\n\t\t\texpectedValue:    `\"Georgia\", monospaced, sans-serif`,\n\t\t},\n\t\t{\n\t\t\tname:             \"font-family Chinese names are allowed\",\n\t\t\tinputProperty:    \"font-family\",\n\t\t\texpectedProperty: \"font-family\",\n\t\t\tinputValue:       `\"中易宋体\", monospaced`,\n\t\t\texpectedValue:    `\"中易宋体\", monospaced`,\n\t\t},\n\t\t{\n\t\t\tname:             \"font-family quoted values must be terminated\",\n\t\t\tinputProperty:    \"font-family\",\n\t\t\texpectedProperty: \"font-family\",\n\t\t\tinputValue:       `\"quotes`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"font-family non standard names are not allowed\",\n\t\t\tinputProperty:    \"font-family\",\n\t\t\texpectedProperty: \"font-family\",\n\t\t\tinputValue:       `foo@bar`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"obfuscated values are not allowed\",\n\t\t\tinputProperty:    \"width\",\n\t\t\texpectedProperty: \"width\",\n\t\t\tinputValue:       `  e\\\\78preS\\x00Sio/**/n(alert(1337))`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"moz binding blocked\",\n\t\t\tinputProperty:    \"-moz-binding(alert(1337))\",\n\t\t\texpectedProperty: InnocuousPropertyName,\n\t\t\tinputValue:       `something`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"obfuscated moz-binding blocked\",\n\t\t\tinputProperty:    \"  -mo\\\\7a-B\\x00I/**/nding(alert(1337))\",\n\t\t\texpectedProperty: InnocuousPropertyName,\n\t\t\tinputValue:       `something`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"angle brackets in property value\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(/img?name=O'Reilly Animal(1)<2>.png)`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"angle brackets in quoted property value\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"/img?name=O'Reilly Animal(1)<2>.png\")`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background\",\n\t\t\tinputProperty:    \"background\",\n\t\t\texpectedProperty: \"background\",\n\t\t\tinputValue:       \"url(/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png)\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image JS URL\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(javascript:alert(1337))`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image VBScript URL\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(vbscript:alert(1337))`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image absolute FTP URL\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"ftp://safe.example.com/img.png\")`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image invalid URL\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"` + string([]byte{0x7f}) + `\")`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image invalid prefix\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `/img.png\")`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image invalid suffix\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"/img.png`,\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image safe URL\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"/img.png\")`,\n\t\t\texpectedValue:    `url(\"/img.png\")`,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image safe URL - two slashes\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"//img.png\")`,\n\t\t\texpectedValue:    `url(\"//img.png\")`,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image safe HTTP URL\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"http://safe.example.com/img.png\")`,\n\t\t\texpectedValue:    `url(\"http://safe.example.com/img.png\")`,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image safe mailto URL\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"mailto:foo@bar.foo\")`,\n\t\t\texpectedValue:    `url(\"mailto:foo@bar.foo\")`,\n\t\t},\n\t\t{\n\t\t\tname:             \"background-image multiple URLs\",\n\t\t\tinputProperty:    \"background-image\",\n\t\t\texpectedProperty: \"background-image\",\n\t\t\tinputValue:       `url(\"http://safe.example.com/img.png\"), url(\"https://safe.example.com/other.png\")`,\n\t\t\texpectedValue:    `url(\"http://safe.example.com/img.png\"), url(\"https://safe.example.com/other.png\")`,\n\t\t},\n\t\t{\n\t\t\tname:             \"-webkit-text-stroke-color safe webkit\",\n\t\t\tinputProperty:    \"-webkit-text-stroke-color\",\n\t\t\texpectedProperty: \"-webkit-text-stroke-color\",\n\t\t\tinputValue:       `#000`,\n\t\t\texpectedValue:    `#000`,\n\t\t},\n\t\t{\n\t\t\tname:             \"escape attempt property name\",\n\t\t\tinputProperty:    \"</style><script>alert('hello')</script><style>\",\n\t\t\texpectedProperty: InnocuousPropertyName,\n\t\t\tinputValue:       \"test\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"escape attempt property value\",\n\t\t\tinputProperty:    \"bottom\",\n\t\t\texpectedProperty: \"bottom\",\n\t\t\tinputValue:       \"</style><script>alert('hello')</script><style>\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"encoded protocol is blocked\",\n\t\t\tinputProperty:    \"bottom\",\n\t\t\texpectedProperty: \"bottom\",\n\t\t\tinputValue:       \"javascript\\\\3a alert(1337)\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"angle brackets 1\",\n\t\t\tinputProperty:    \"bottom\",\n\t\t\texpectedProperty: \"bottom\",\n\t\t\tinputValue:       \"x<\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"angle brackets 2\",\n\t\t\tinputProperty:    \"bottom\",\n\t\t\texpectedProperty: \"bottom\",\n\t\t\tinputValue:       \"x>\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"contains colon\",\n\t\t\tinputProperty:    \"bottom\",\n\t\t\texpectedProperty: \"bottom\",\n\t\t\tinputValue:       \":\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"contains semicolon\",\n\t\t\tinputProperty:    \"bottom\",\n\t\t\texpectedProperty: \"bottom\",\n\t\t\tinputValue:       \";\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"comments are removed #1\",\n\t\t\tinputProperty:    \"background-repeat\",\n\t\t\texpectedProperty: \"background-repeat\",\n\t\t\tinputValue:       \"// removed\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"comments are removed #2\",\n\t\t\tinputProperty:    \"background-repeat\",\n\t\t\texpectedProperty: \"background-repeat\",\n\t\t\tinputValue:       \"/* removed\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"comments are removed #3\",\n\t\t\tinputProperty:    \"background-repeat\",\n\t\t\texpectedProperty: \"background-repeat\",\n\t\t\tinputValue:       \"/* removed\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"comments are sanitized mid value #1\",\n\t\t\tinputProperty:    \"background-repeat\",\n\t\t\texpectedProperty: \"background-repeat\",\n\t\t\tinputValue:       \"repeat-none // removed\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"comments are sanitized mid value #2\",\n\t\t\tinputProperty:    \"background-repeat\",\n\t\t\texpectedProperty: \"background-repeat\",\n\t\t\tinputValue:       \"repeat-none /* removed\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"comments are sanitized mid value #3\",\n\t\t\tinputProperty:    \"background-repeat\",\n\t\t\texpectedProperty: \"background-repeat\",\n\t\t\tinputValue:       \"repeat-none /* removed\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"bad characters in value\",\n\t\t\tinputProperty:    \"background-repeat\",\n\t\t\texpectedProperty: \"background-repeat\",\n\t\t\tinputValue:       \"This&is$bad\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"enum values must be valid\",\n\t\t\tinputProperty:    \"display\",\n\t\t\texpectedProperty: \"display\",\n\t\t\tinputValue:       \"badValue123\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"values cannot contain newlines at start\",\n\t\t\tinputProperty:    \"display\",\n\t\t\texpectedProperty: \"display\",\n\t\t\tinputValue:       \"\\ntest\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"values cannot contain newlines at end\",\n\t\t\tinputProperty:    \"display\",\n\t\t\texpectedProperty: \"display\",\n\t\t\tinputValue:       \"test\\n\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t\t{\n\t\t\tname:             \"some symbols are allowed\",\n\t\t\tinputProperty:    \"display\",\n\t\t\texpectedProperty: \"display\",\n\t\t\tinputValue:       \"*+/-.!#%_ \\t\",\n\t\t\texpectedValue:    InnocuousPropertyValue,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tactualProperty, actualValue := SanitizeCSS(tt.inputProperty, tt.inputValue)\n\t\t\tif actualProperty != tt.expectedProperty {\n\t\t\t\tt.Errorf(\"%s: mismatched property - expected %q, actual %q\", tt.name, tt.expectedProperty, actualProperty)\n\t\t\t}\n\t\t\tif actualValue != tt.expectedValue {\n\t\t\t\tt.Errorf(\"%s: mismatched value - expected %q, actual %q\", tt.name, tt.expectedValue, actualValue)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "scripttemplate.go",
    "content": "package templ\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"html\"\n\t\"io\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// ComponentScript is a templ Script template.\ntype ComponentScript struct {\n\t// Name of the script, e.g. print.\n\tName string\n\t// Function to render.\n\tFunction string\n\t// Call of the function in JavaScript syntax, including parameters, and\n\t// ensures parameters are HTML escaped; useful for injecting into HTML\n\t// attributes like onclick, onhover, etc.\n\t//\n\t// Given:\n\t//    functionName(\"some string\",12345)\n\t// It would render:\n\t//    __templ_functionName_sha(&#34;some string&#34;,12345))\n\t//\n\t// This is can be injected into HTML attributes:\n\t//    <button onClick=\"__templ_functionName_sha(&#34;some string&#34;,12345))\">Click Me</button>\n\tCall string\n\t// Call of the function in JavaScript syntax, including parameters. It\n\t// does not HTML escape parameters; useful for directly calling in script\n\t// elements.\n\t//\n\t// Given:\n\t//    functionName(\"some string\",12345)\n\t// It would render:\n\t//    __templ_functionName_sha(\"some string\",12345))\n\t//\n\t// This is can be used to call the function inside a script tag:\n\t//    <script>__templ_functionName_sha(\"some string\",12345))</script>\n\tCallInline string\n}\n\nvar _ Component = ComponentScript{}\n\nfunc writeScriptHeader(ctx context.Context, w io.Writer) (err error) {\n\tvar nonceAttr string\n\tif nonce := GetNonce(ctx); nonce != \"\" {\n\t\tnonceAttr = \" nonce=\\\"\" + EscapeString(nonce) + \"\\\"\"\n\t}\n\t_, err = fmt.Fprintf(w, `<script%s>`, nonceAttr)\n\treturn err\n}\n\nfunc (c ComponentScript) Render(ctx context.Context, w io.Writer) error {\n\terr := RenderScriptItems(ctx, w, c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(c.Call) > 0 {\n\t\tif err = writeScriptHeader(ctx, w); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = io.WriteString(w, c.CallInline); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = io.WriteString(w, `</script>`); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// RenderScriptItems renders a <script> element, if the script has not already been rendered.\nfunc RenderScriptItems(ctx context.Context, w io.Writer, scripts ...ComponentScript) (err error) {\n\tif len(scripts) == 0 {\n\t\treturn nil\n\t}\n\t_, v := getContext(ctx)\n\tsb := new(strings.Builder)\n\tfor _, s := range scripts {\n\t\tif !v.hasScriptBeenRendered(s.Name) {\n\t\t\tsb.WriteString(s.Function)\n\t\t\tv.addScript(s.Name)\n\t\t}\n\t}\n\tif sb.Len() > 0 {\n\t\tif err = writeScriptHeader(ctx, w); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = io.WriteString(w, sb.String()); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = io.WriteString(w, `</script>`); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// JSExpression represents a JavaScript expression intended for use as an argument for script templates.\n// The string value of JSExpression will be inserted directly as JavaScript code in function call arguments.\ntype JSExpression string\n\n// SafeScript encodes unknown parameters for safety for inside HTML attributes.\nfunc SafeScript(functionName string, params ...any) string {\n\tif !jsFunctionName.MatchString(functionName) {\n\t\tfunctionName = \"__templ_invalid_js_function_name\"\n\t}\n\tsb := new(strings.Builder)\n\tsb.WriteString(html.EscapeString(functionName))\n\tsb.WriteRune('(')\n\tfor i, p := range params {\n\t\tsb.WriteString(EscapeString(jsonEncodeParam(p)))\n\t\tif i < len(params)-1 {\n\t\t\tsb.WriteRune(',')\n\t\t}\n\t}\n\tsb.WriteRune(')')\n\treturn sb.String()\n}\n\n// SafeScript encodes unknown parameters for safety for inline scripts.\nfunc SafeScriptInline(functionName string, params ...any) string {\n\tif !jsFunctionName.MatchString(functionName) {\n\t\tfunctionName = \"__templ_invalid_js_function_name\"\n\t}\n\tsb := new(strings.Builder)\n\tsb.WriteString(functionName)\n\tsb.WriteRune('(')\n\tfor i, p := range params {\n\t\tsb.WriteString(jsonEncodeParam(p))\n\t\tif i < len(params)-1 {\n\t\t\tsb.WriteRune(',')\n\t\t}\n\t}\n\tsb.WriteRune(')')\n\treturn sb.String()\n}\n\nfunc jsonEncodeParam(param any) string {\n\tif val, ok := param.(JSExpression); ok {\n\t\treturn string(val)\n\t}\n\tenc, _ := json.Marshal(param)\n\treturn string(enc)\n}\n\n// isValidJSFunctionName returns true if the given string is a valid JavaScript function name, e.g. console.log, alert, etc.\nvar jsFunctionName = regexp.MustCompile(`^([$_a-zA-Z][$_a-zA-Z0-9]+\\.?)+$`)\n"
  },
  {
    "path": "scripttemplate_test.go",
    "content": "package templ_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestRenderScriptItems(t *testing.T) {\n\ts1 := templ.ComponentScript{\n\t\tName:     \"s1\",\n\t\tFunction: \"function s1() { return 'hello1'; }\",\n\t}\n\ts2 := templ.ComponentScript{\n\t\tName:     \"s2\",\n\t\tFunction: \"function s2() { return 'hello2'; }\",\n\t}\n\ttests := []struct {\n\t\tname     string\n\t\ttoIgnore []templ.ComponentScript\n\t\ttoRender []templ.ComponentScript\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"if none are ignored, everything is rendered\",\n\t\t\ttoIgnore: nil,\n\t\t\ttoRender: []templ.ComponentScript{s1, s2},\n\t\t\texpected: `<script>` + s1.Function + s2.Function + `</script>`,\n\t\t},\n\t\t{\n\t\t\tname: \"if something outside the expected is ignored, if has no effect\",\n\t\t\ttoIgnore: []templ.ComponentScript{\n\t\t\t\t{\n\t\t\t\t\tName:     \"s3\",\n\t\t\t\t\tFunction: \"function s3() { return 'hello3'; }\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttoRender: []templ.ComponentScript{s1, s2},\n\t\t\texpected: `<script>` + s1.Function + s2.Function + `</script>`,\n\t\t},\n\t\t{\n\t\t\tname:     \"if one is ignored, it's not rendered\",\n\t\t\ttoIgnore: []templ.ComponentScript{s1},\n\t\t\ttoRender: []templ.ComponentScript{s1, s2},\n\t\t\texpected: `<script>` + s2.Function + `</script>`,\n\t\t},\n\t\t{\n\t\t\tname: \"if all are ignored, not even style tags are rendered\",\n\t\t\ttoIgnore: []templ.ComponentScript{\n\t\t\t\ts1,\n\t\t\t\ts2,\n\t\t\t\t{\n\t\t\t\t\tName:     \"s3\",\n\t\t\t\t\tFunction: \"function s3() { return 'hello3'; }\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttoRender: []templ.ComponentScript{s1, s2},\n\t\t\texpected: ``,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\ttt := tt\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\t\t\tb := new(bytes.Buffer)\n\n\t\t\t// Render twice, reusing the same context so that there's a memory of which classes have been rendered.\n\t\t\tctx = templ.InitializeContext(ctx)\n\t\t\terr := templ.RenderScriptItems(ctx, b, tt.toIgnore...)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to render initial scripts: %v\", err)\n\t\t\t}\n\n\t\t\t// Now render again to check that only the expected classes were rendered.\n\t\t\tb.Reset()\n\t\t\terr = templ.RenderScriptItems(ctx, b, tt.toRender...)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"failed to render scripts: %v\", err)\n\t\t\t}\n\n\t\t\tif diff := cmp.Diff(tt.expected, b.String()); diff != \"\" {\n\t\t\t\tt.Error(diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestJSExpression(t *testing.T) {\n\texpected := \"myJSFunction(\\\"StringValue\\\",123,event,1 + 2)\"\n\tactual := templ.SafeScriptInline(\"myJSFunction\", \"StringValue\", 123, templ.JSExpression(\"event\"), templ.JSExpression(\"1 + 2\"))\n\n\tif actual != expected {\n\t\tt.Fatalf(\"TestJSExpression: expected %q, got %q\", expected, actual)\n\t}\n}\n"
  },
  {
    "path": "storybook/.gitignore",
    "content": "storybook-server\n\n*storybook.log\n"
  },
  {
    "path": "storybook/_example/cdk/.gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# go.sum should be committed\n!go.sum\n\n# CDK asset staging directory\n.cdk.staging\ncdk.out\n"
  },
  {
    "path": "storybook/_example/cdk/README.md",
    "content": "# Welcome to your CDK Go project!\n\nThis is a blank project for Go development with CDK.\n\n**NOTICE**: Go support is still in Developer Preview. This implies that APIs may\nchange while we address early feedback from the community. We would love to hear\nabout your experience through GitHub issues.\n\n## Useful commands\n\n * `cdk deploy`      deploy this stack to your default AWS account/region\n * `cdk diff`        compare deployed stack with current state\n * `cdk synth`       emits the synthesized CloudFormation template\n * `go test`         run unit tests\n"
  },
  {
    "path": "storybook/_example/cdk/cdk.go",
    "content": "package main\n\nimport (\n\t\"github.com/aws/aws-cdk-go/awscdk/v2\"\n\t\"github.com/aws/aws-cdk-go/awscdk/v2/awslambda\"\n\t\"github.com/aws/aws-cdk-go/awscdkapigatewayv2alpha/v2\"\n\tawsapigatewayv2 \"github.com/aws/aws-cdk-go/awscdkapigatewayv2alpha/v2\"\n\tawsapigatewayv2integrations \"github.com/aws/aws-cdk-go/awscdkapigatewayv2integrationsalpha/v2\"\n\tawslambdago \"github.com/aws/aws-cdk-go/awscdklambdagoalpha/v2\"\n\t\"github.com/aws/constructs-go/constructs/v10\"\n\t\"github.com/aws/jsii-runtime-go\"\n)\n\ntype CdkStackProps struct {\n\tawscdk.StackProps\n}\n\nfunc NewCdkStack(scope constructs.Construct, id string, props *CdkStackProps) awscdk.Stack {\n\tvar sprops awscdk.StackProps\n\tif props != nil {\n\t\tsprops = props.StackProps\n\t}\n\tstack := awscdk.NewStack(scope, &id, &sprops)\n\n\tbundlingOptions := &awslambdago.BundlingOptions{\n\t\tGoBuildFlags: &[]*string{jsii.String(`-ldflags \"-s -w\"`)},\n\t}\n\n\tf := awslambdago.NewGoFunction(stack, jsii.String(\"storybookHandler\"), &awslambdago.GoFunctionProps{\n\t\tRuntime:    awslambda.Runtime_GO_1_X(),\n\t\tEntry:      jsii.String(\"../lambda\"),\n\t\tBundling:   bundlingOptions,\n\t\tMemorySize: jsii.Number(1024),\n\t\tTimeout:    awscdk.Duration_Millis(jsii.Number(15000)),\n\t})\n\tfi := awsapigatewayv2integrations.NewHttpLambdaIntegration(jsii.String(\"handlerIntegration\"), f, &awsapigatewayv2integrations.HttpLambdaIntegrationProps{\n\t\tPayloadFormatVersion: awscdkapigatewayv2alpha.PayloadFormatVersion_VERSION_2_0(),\n\t})\n\tendpoint := awsapigatewayv2.NewHttpApi(stack, jsii.String(\"storybookHttpApi\"), &awsapigatewayv2.HttpApiProps{\n\t\tDefaultIntegration: fi,\n\t})\n\tawscdk.NewCfnOutput(stack, jsii.String(\"storybookEndpointUrl\"), &awscdk.CfnOutputProps{\n\t\tExportName: jsii.String(\"storybookEndpointUrl\"),\n\t\tValue:      endpoint.Url(),\n\t})\n\n\treturn stack\n}\n\nfunc main() {\n\tapp := awscdk.NewApp(nil)\n\n\tNewCdkStack(app, \"templStorybookExample\", &CdkStackProps{\n\t\tawscdk.StackProps{\n\t\t\tEnv: env(),\n\t\t},\n\t})\n\n\tapp.Synth(nil)\n}\n\n// env determines the AWS environment (account+region) in which our stack is to\n// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html\nfunc env() *awscdk.Environment {\n\t// If unspecified, this stack will be \"environment-agnostic\".\n\t// Account/Region-dependent features and context lookups will not work, but a\n\t// single synthesized template can be deployed anywhere.\n\t//---------------------------------------------------------------------------\n\treturn nil\n\n\t// Uncomment if you know exactly what account and region you want to deploy\n\t// the stack to. This is the recommendation for production stacks.\n\t//---------------------------------------------------------------------------\n\t// return &awscdk.Environment{\n\t//  Account: jsii.String(\"123456789012\"),\n\t//  Region:  jsii.String(\"us-east-1\"),\n\t// }\n\n\t// Uncomment to specialize this stack for the AWS Account and Region that are\n\t// implied by the current CLI configuration. This is recommended for dev\n\t// stacks.\n\t//---------------------------------------------------------------------------\n\t// return &awscdk.Environment{\n\t//  Account: jsii.String(os.Getenv(\"CDK_DEFAULT_ACCOUNT\")),\n\t//  Region:  jsii.String(os.Getenv(\"CDK_DEFAULT_REGION\")),\n\t// }\n}\n"
  },
  {
    "path": "storybook/_example/cdk/cdk.json",
    "content": "{\n  \"app\": \"go mod download && go run cdk.go\",\n  \"context\": {\n    \"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId\": true,\n    \"@aws-cdk/core:enableStackNameDuplicates\": \"true\",\n    \"aws-cdk:enableDiffNoFail\": \"true\",\n    \"@aws-cdk/core:stackRelativeExports\": \"true\",\n    \"@aws-cdk/aws-ecr-assets:dockerIgnoreSupport\": true,\n    \"@aws-cdk/aws-secretsmanager:parseOwnedSecretName\": true,\n    \"@aws-cdk/aws-kms:defaultKeyPolicies\": true,\n    \"@aws-cdk/aws-s3:grantWriteWithoutAcl\": true,\n    \"@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount\": true,\n    \"@aws-cdk/aws-rds:lowercaseDbIdentifier\": true,\n    \"@aws-cdk/aws-efs:defaultEncryptionAtRest\": true,\n    \"@aws-cdk/aws-lambda:recognizeVersionProps\": true,\n    \"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021\": true\n  }\n}\n"
  },
  {
    "path": "storybook/_example/cdk/deploy.sh",
    "content": "# Build the Storybook.\n`cd ../lambda && go run main.go build`\n# Deploy it.\ncdk deploy\n"
  },
  {
    "path": "storybook/_example/go.mod",
    "content": "module github.com/a-h/templ/storybook/example\n\ngo 1.23.0\n\ntoolchain go1.24.3\n\nreplace github.com/a-h/templ => ../../\n\nrequire (\n\tgithub.com/a-h/templ v0.0.0-00010101000000-000000000000\n\tgithub.com/aws/aws-cdk-go/awscdk/v2 v2.25.0\n\tgithub.com/aws/aws-cdk-go/awscdkapigatewayv2alpha/v2 v2.25.0-alpha.0\n\tgithub.com/aws/aws-cdk-go/awscdkapigatewayv2integrationsalpha/v2 v2.25.0-alpha.0\n\tgithub.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.25.0-alpha.0\n\tgithub.com/aws/aws-lambda-go v1.27.0\n\tgithub.com/aws/constructs-go/constructs/v10 v10.1.20\n\tgithub.com/aws/jsii-runtime-go v1.59.0\n)\n\nrequire (\n\tgithub.com/Masterminds/semver/v3 v3.1.1 // indirect\n\tgithub.com/rs/cors v1.11.0 // indirect\n\tgolang.org/x/mod v0.26.0 // indirect\n)\n"
  },
  {
    "path": "storybook/_example/go.sum",
    "content": "github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=\ngithub.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=\ngithub.com/aws/aws-cdk-go/awscdk/v2 v2.25.0 h1:lTVj41TEVZBfKQ7btNSvBkCYuLw7Y60XXYpNBlhtjkM=\ngithub.com/aws/aws-cdk-go/awscdk/v2 v2.25.0/go.mod h1:7XCtayiRILOHD/BkEyvxuqdrAHBt6dMXhSNcLm0ihU8=\ngithub.com/aws/aws-cdk-go/awscdkapigatewayv2alpha/v2 v2.25.0-alpha.0 h1:5hqUcKS5O1p8LkYLFg0Mv0lA+t3+wz49AdDSSokBv3c=\ngithub.com/aws/aws-cdk-go/awscdkapigatewayv2alpha/v2 v2.25.0-alpha.0/go.mod h1:kaKSDRgZeseFVVr3Qr4m+0XZ2U1idkkMjVsZbfG2XVE=\ngithub.com/aws/aws-cdk-go/awscdkapigatewayv2integrationsalpha/v2 v2.25.0-alpha.0 h1:KTvckM8FJ/aeSq7oGWlMlO99YaXlP4VVEOJGGHW+BjI=\ngithub.com/aws/aws-cdk-go/awscdkapigatewayv2integrationsalpha/v2 v2.25.0-alpha.0/go.mod h1:0gUU7nJB0/Y6ukGLQfcFKDX/MODXK37WBVltZl610sY=\ngithub.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.25.0-alpha.0 h1:XZ0FpvZ4uPZ911REuISvTesA+71wllTCodhJa0p+9ug=\ngithub.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.25.0-alpha.0/go.mod h1:cKT1tzcwvqHmRiih7eDFC0Kz1RsPys+727RkNbJAgaU=\ngithub.com/aws/aws-lambda-go v1.27.0 h1:aLzrJwdyHoF1A18YeVdJjX8Ixkd+bpogdxVInvHcWjM=\ngithub.com/aws/aws-lambda-go v1.27.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU=\ngithub.com/aws/constructs-go/constructs/v10 v10.0.9/go.mod h1:RC6w8bOwxLmPX7Jfo9dkEZ9iVfgH4QnaVnfWvaNOHy0=\ngithub.com/aws/constructs-go/constructs/v10 v10.1.20 h1:NQnZbzsssleUh+s10mRlRMSLDX0ETfZjLUEu6QxeBUg=\ngithub.com/aws/constructs-go/constructs/v10 v10.1.20/go.mod h1:XFwFvzuX38hhTlpNVlC1tpgjCpRAAVr7a6+O0/9VB9c=\ngithub.com/aws/jsii-runtime-go v1.37.0/go.mod h1:6tZnlstx8bAB3vnLFF9n8bbkI//LDblAek9zFyMXV3E=\ngithub.com/aws/jsii-runtime-go v1.58.0/go.mod h1:OPeobFzUctDjq8EXbRZbIphpzQg3lzMs8KH09xuHyk0=\ngithub.com/aws/jsii-runtime-go v1.59.0 h1:QEnIpd17oKv/UMFD2bPxLbT3B3S+QlYTmnPHEdKJkic=\ngithub.com/aws/jsii-runtime-go v1.59.0/go.mod h1:OPeobFzUctDjq8EXbRZbIphpzQg3lzMs8KH09xuHyk0=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=\ngithub.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=\ngolang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=\ngolang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "storybook/_example/lambda/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"embed\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\n\t\"github.com/a-h/templ/storybook/example\"\n\t\"github.com/aws/aws-lambda-go/events\"\n\t\"github.com/aws/aws-lambda-go/lambda\"\n)\n\nvar s = example.Storybook()\n\nfunc build() {\n\tif err := s.Build(context.Background()); err != nil {\n\t\tfmt.Println(err)\n\t\tos.Exit(1)\n\t}\n}\n\n// Embed the build output into the Lambda.\n// The build output is only 4MB, so there's plenty of space.\n//\n//go:embed storybook-server/storybook-static\nvar storybookStatic embed.FS\n\nfunc run() {\n\t// Replace the filesystem handler with the embedded data.\n\trooted, _ := fs.Sub(storybookStatic, \"storybook-server/storybook-static\")\n\ts.StaticHandler = http.FileServer(http.FS(rooted))\n\t// Start a Lambda handler.\n\tlambda.Start(handler)\n}\n\nfunc handler(ctx context.Context, e events.APIGatewayV2HTTPRequest) (resp events.APIGatewayV2HTTPResponse, err error) {\n\t// Record the result.\n\tw := httptest.NewRecorder()\n\tu := e.RawPath\n\tif len(e.RawQueryString) > 0 {\n\t\tu += \"?\" + e.RawQueryString\n\t}\n\tr := httptest.NewRequest(e.RequestContext.HTTP.Method, u, nil)\n\ts.ServeHTTP(w, r)\n\n\t// Convert it to an API Gateway response.\n\tresult := w.Result()\n\tresp.StatusCode = result.StatusCode\n\tbdy, err := io.ReadAll(w.Result().Body)\n\tif err != nil {\n\t\treturn\n\t}\n\tresp.Body = string(bdy)\n\tif len(result.Header) > 0 {\n\t\tresp.Headers = make(map[string]string, len(result.Header))\n\t\tfor k := range result.Header {\n\t\t\tv := result.Header.Get(k)\n\t\t\tresp.Headers[k] = v\n\t\t}\n\t}\n\tcookies := result.Cookies()\n\tif len(cookies) > 0 {\n\t\tresp.Cookies = make([]string, len(cookies))\n\t\tfor i, c := range cookies {\n\t\t\tresp.Cookies[i] = c.String()\n\t\t}\n\t}\n\treturn\n}\n\nfunc main() {\n\tif len(os.Args) < 2 {\n\t\trun()\n\t}\n\tswitch os.Args[1] {\n\tcase \"build\":\n\t\tbuild()\n\tcase \"run\":\n\t\trun()\n\tdefault:\n\t\tfmt.Printf(\"unexpected command %q\\n\", os.Args[1])\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "storybook/_example/local/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/a-h/templ/storybook/example\"\n)\n\nfunc main() {\n\ts := example.Storybook()\n\tif err := s.ListenAndServeWithContext(context.Background()); err != nil {\n\t\tfmt.Println(err.Error())\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "storybook/_example/run.sh",
    "content": "go run ./local/main.go\n"
  },
  {
    "path": "storybook/_example/storybook.go",
    "content": "package example\n\nimport (\n\t\"github.com/a-h/templ/storybook\"\n)\n\nfunc Storybook() *storybook.Storybook {\n\ts := storybook.New()\n\n\theader := s.AddComponent(\"headerTemplate\", headerTemplate, storybook.TextArg(\"name\", \"Page Name\"))\n\theader.AddStory(\"Long Name\", storybook.TextArg(\"name\", \"A Very Long Page Name\"))\n\n\ts.AddComponent(\"footerTemplate\", footerTemplate)\n\n\treturn s\n}\n"
  },
  {
    "path": "storybook/_example/templates.templ",
    "content": "package example\n\nimport \"fmt\"\nimport \"time\"\n\ntempl headerTemplate(name string) {\n\t<header data-testid=\"headerTemplate\">\n\t\t<h1>{ name }</h1>\n\t</header>\n}\n\ntempl footerTemplate() {\n\t<footer data-testid=\"footerTemplate\">\n\t\t<div>&copy; { fmt.Sprintf(\"%d\", time.Now().Year()) }</div>\n\t</footer>\n}\n\n"
  },
  {
    "path": "storybook/_example/templates_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage example\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nimport \"fmt\"\nimport \"time\"\n\nfunc headerTemplate(name string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(\"<header data-testid=\\\"headerTemplate\\\"><h1>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `storybook/_example/templates.templ`, Line: 10, Col: 12}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(\"</h1></header>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn templ_7745c5c3_Err\n\t})\n}\n\nfunc footerTemplate() templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var3 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var3 == nil {\n\t\t\ttempl_7745c5c3_Var3 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(\"<footer data-testid=\\\"footerTemplate\\\"><div>&copy; \")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var4 string\n\t\ttempl_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(\"%d\", time.Now().Year()))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `storybook/_example/templates.templ`, Line: 16, Col: 52}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(\"</div></footer>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn templ_7745c5c3_Err\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "storybook/_package.json",
    "content": "{\n  \"name\": \"storybook-server\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"author\": \"\",\n  \"description\": \"\"\n}\n"
  },
  {
    "path": "storybook/storybook.go",
    "content": "package storybook\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"math\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"golang.org/x/mod/sumdb/dirhash\"\n\n\t_ \"embed\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/rs/cors\"\n)\n\ntype Storybook struct {\n\t// Path to the storybook-server directory, defaults to ./storybook-server.\n\tPath string\n\t// RoutePrefix is the prefix of HTTP routes, e.g. /prod/\n\tRoutePrefix string\n\t// Config of the Stories.\n\tConfig map[string]*Conf\n\t// Handlers for each of the components.\n\tHandlers map[string]http.Handler\n\t// Handler used to serve Storybook, defaults to filesystem at ./storybook-server/storybook-static.\n\tStaticHandler      http.Handler\n\tHeader             string\n\tServer             http.Server\n\tLog                *slog.Logger\n\tAdditionalPrefixJS string\n}\n\ntype StorybookConfig func(*Storybook)\n\nfunc WithServerAddr(addr string) StorybookConfig {\n\treturn func(sb *Storybook) {\n\t\tsb.Server.Addr = addr\n\t}\n}\n\nfunc WithHeader(header string) StorybookConfig {\n\treturn func(s *Storybook) {\n\t\ts.Header = header\n\t}\n}\n\nfunc WithPath(path string) StorybookConfig {\n\treturn func(sb *Storybook) {\n\t\tsb.Path = path\n\t}\n}\n\n// WithAdditionalPreviewJS / WithAdditionalPreviewJS allows to add content to the generated .storybook/preview.js file.\n// For example this can be used to include custom CSS.\nfunc WithAdditionalPreviewJS(content string) StorybookConfig {\n\treturn func(sb *Storybook) {\n\t\tsb.AdditionalPrefixJS = content\n\t}\n}\n\nfunc New(conf ...StorybookConfig) *Storybook {\n\tlogger := slog.New(slog.NewJSONHandler(os.Stderr, nil))\n\tsh := &Storybook{\n\t\tPath:     \"./storybook-server\",\n\t\tConfig:   map[string]*Conf{},\n\t\tHandlers: map[string]http.Handler{},\n\t\tLog:      logger,\n\t}\n\tsh.Server = http.Server{\n\t\tHandler: sh,\n\t\tAddr:    \":60606\",\n\t}\n\tfor _, sc := range conf {\n\t\tsc(sh)\n\t}\n\n\t// Depends on the correct Path, so must be set after additional config\n\tsh.StaticHandler = http.FileServer(http.Dir(path.Join(sh.Path, \"storybook-static\")))\n\n\treturn sh\n}\n\nfunc (sh *Storybook) AddComponent(name string, componentConstructor any, args ...Arg) *Conf {\n\t// TODO: Check that the component constructor is a function that returns a templ.Component.\n\tc := NewConf(name, args...)\n\tsh.Config[name] = c\n\th := NewHandler(name, componentConstructor, args...)\n\tsh.Handlers[name] = h\n\treturn c\n}\n\nfunc (sh *Storybook) Build(ctx context.Context) (err error) {\n\t// Download Storybook to the directory required.\n\tsh.Log.Info(\"Installing storybook.\")\n\terr = sh.installStorybook()\n\tif err != nil {\n\t\treturn\n\t}\n\tif err = ctx.Err(); err != nil {\n\t\treturn\n\t}\n\n\t// Copy the config to Storybook.\n\tsh.Log.Info(\"Configuring storybook.\")\n\tconfigHasChanged, err := sh.configureStorybook()\n\tif err != nil {\n\t\treturn\n\t}\n\tif err = ctx.Err(); err != nil {\n\t\treturn\n\t}\n\n\t// Execute a static build of storybook if the config has changed.\n\tif configHasChanged {\n\t\tsh.Log.Info(\"Config not present, or has changed, rebuilding storybook.\")\n\t\terr = sh.buildStorybook()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t} else {\n\t\tsh.Log.Info(\"Storybook is up-to-date, skipping build step.\")\n\t}\n\tif err = ctx.Err(); err != nil {\n\t\treturn\n\t}\n\n\treturn\n}\n\nfunc (sh *Storybook) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tsbh := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tif strings.HasPrefix(r.URL.Path, path.Join(sh.RoutePrefix, \"/storybook_preview/\")) {\n\t\t\tsh.previewHandler(w, r)\n\t\t\treturn\n\t\t}\n\t\tsh.StaticHandler.ServeHTTP(w, r)\n\t})\n\tcors.Default().Handler(sbh).ServeHTTP(w, r)\n}\n\nfunc (sh *Storybook) ListenAndServeWithContext(ctx context.Context) (err error) {\n\terr = sh.Build(ctx)\n\tif err != nil {\n\t\treturn\n\t}\n\tgo func() {\n\t\tsh.Log.Info(\"Starting Go server\", slog.String(\"address\", sh.Server.Addr))\n\t\terr = sh.Server.ListenAndServe()\n\t}()\n\t<-ctx.Done()\n\t// Close the Go server.\n\t_ = sh.Server.Close()\n\treturn err\n}\n\nfunc (sh *Storybook) previewHandler(w http.ResponseWriter, r *http.Request) {\n\tprefix := path.Join(sh.RoutePrefix, \"/storybook_preview/\")\n\tif !strings.HasPrefix(r.URL.Path, prefix) {\n\t\tsh.Log.Warn(\"URL does not match preview prefix\", slog.String(\"url\", r.URL.String()))\n\t\thttp.NotFound(w, r)\n\t\treturn\n\t}\n\n\tname, err := url.PathUnescape(strings.TrimPrefix(r.URL.Path, prefix))\n\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"failed to unescape URL: %v\", err), http.StatusBadRequest)\n\t\treturn\n\t}\n\tif name == \"\" {\n\t\tsh.Log.Warn(\"URL does not contain component name\", slog.String(\"url\", r.URL.String()))\n\t\thttp.NotFound(w, r)\n\t\treturn\n\t}\n\tname = strings.TrimPrefix(name, \"/\")\n\n\th, found := sh.Handlers[name]\n\tif !found {\n\t\tsh.Log.Info(\"Component name not found\", slog.String(\"name\", name), slog.String(\"url\", r.URL.String()), slog.Any(\"available\", keysOfMap(sh.Handlers)))\n\t\thttp.NotFound(w, r)\n\t\treturn\n\t}\n\th.ServeHTTP(w, r)\n}\n\nfunc keysOfMap[K comparable, V any](handler map[K]V) (keys []K) {\n\tkeys = make([]K, len(handler))\n\tvar i int\n\tfor k := range handler {\n\t\tkeys[i] = k\n\t\ti++\n\t}\n\treturn keys\n}\n\n//go:embed _package.json\nvar packageJSON string\n\nfunc (sh *Storybook) installStorybook() (err error) {\n\t_, err = os.Stat(sh.Path)\n\tif err == nil {\n\t\tsh.Log.Info(\"Storybook already installed, Skipping installation.\")\n\t\treturn\n\t}\n\tif os.IsNotExist(err) {\n\t\terr = os.Mkdir(sh.Path, os.ModePerm)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"templ-storybook: error creating @storybook/server directory: %w\", err)\n\t\t}\n\t\terr = os.WriteFile(filepath.Join(sh.Path, \"package.json\"), []byte(packageJSON), 0644)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"templ-storybook: error writing package.json: %w\", err)\n\t\t}\n\t}\n\tvar cmd exec.Cmd\n\tcmd.Dir = sh.Path\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\tcmd.Path, err = exec.LookPath(\"npx\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"templ-storybook: cannot install storybook, cannot find npx on the path, check that Node.js is installed: %w\", err)\n\t}\n\tcmd.Args = []string{\"npx\", \"sb\", \"init\", \"--features\", \"docs\", \"test\", \"-t\", \"server\", \"--no-dev\"}\n\treturn cmd.Run()\n}\n\nfunc (sh *Storybook) configureStorybook() (configHasChanged bool, err error) {\n\t// Delete template/existing files in the stories directory.\n\tstoriesDir := filepath.Join(sh.Path, \"stories\")\n\tbefore, err := dirhash.HashDir(storiesDir, \"/\", dirhash.DefaultHash)\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn configHasChanged, err\n\t}\n\tif err = os.RemoveAll(storiesDir); err != nil {\n\t\treturn configHasChanged, err\n\t}\n\tif err := os.Mkdir(storiesDir, os.ModePerm); err != nil {\n\t\treturn configHasChanged, err\n\t}\n\t// Create new *.stories.json files.\n\tfor _, c := range sh.Config {\n\t\tname := filepath.Join(sh.Path, fmt.Sprintf(\"stories/%s.stories.json\", c.Title))\n\t\tf, err := os.Create(name)\n\t\tif err != nil {\n\t\t\treturn configHasChanged, fmt.Errorf(\"failed to create config file to %q: %w\", name, err)\n\t\t}\n\t\terr = json.NewEncoder(f).Encode(c)\n\t\tif err != nil {\n\t\t\treturn configHasChanged, fmt.Errorf(\"failed to write JSON config to %q: %w\", name, err)\n\t\t}\n\t}\n\tafter, err := dirhash.HashDir(storiesDir, \"/\", dirhash.DefaultHash)\n\tif err != nil {\n\t\treturn configHasChanged, fmt.Errorf(\"failed to hash directory %q: %w\", storiesDir, err)\n\t}\n\tconfigHasChanged = before != after\n\t// Configure storybook Preview URL.\n\terr = os.WriteFile(filepath.Join(sh.Path, \".storybook/preview.js\"), []byte(fmt.Sprintf(\"%s\\n%s\", sh.AdditionalPrefixJS, previewJS)), os.ModePerm)\n\tif err != nil {\n\t\treturn\n\t}\n\t// Configure preview-head.html\n\terr = os.WriteFile(filepath.Join(sh.Path, \".storybook/preview-head.html\"), []byte(sh.Header), os.ModePerm)\n\treturn\n}\n\nvar previewJS = `\n// Customise fetch so that it uses a relative URL.\nconst fetchStoryHtml = async (url, path, params, context) => {\n  const qs = new URLSearchParams(params);\n  const response = await fetch(\"/storybook_preview/\" + path + \"?\" + qs.toString());\n  return response.text();\n};\n\nexport const parameters = {\n  server: {\n    url: \"http://localhost/storybook_preview\", // Ignored by fetchStoryHtml.\n    fetchStoryHtml,\n  },\n};\n`\n\nfunc (sh *Storybook) buildStorybook() (err error) {\n\tvar cmd exec.Cmd\n\tcmd.Dir = sh.Path\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\tcmd.Path, err = exec.LookPath(\"npm\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"templ-storybook: cannot run storybook, cannot find npm on the path, check that Node.js is installed: %w\", err)\n\t}\n\tcmd.Args = []string{\"npm\", \"run\", \"build-storybook\"}\n\treturn cmd.Run()\n}\n\nfunc NewHandler(name string, f any, args ...Arg) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\targv := make([]any, len(args))\n\t\tq := r.URL.Query()\n\t\tfor i, arg := range args {\n\t\t\targv[i] = arg.Get(q)\n\t\t}\n\t\tcomponent, err := executeTemplate(name, f, argv)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\ttempl.Handler(component).ServeHTTP(w, r)\n\t})\n}\n\nfunc executeTemplate(name string, fn any, values []any) (output templ.Component, err error) {\n\tv := reflect.ValueOf(fn)\n\tt := v.Type()\n\targv := make([]reflect.Value, t.NumIn())\n\tif len(argv) != len(values) {\n\t\terr = fmt.Errorf(\"templ-storybook: component %s expects %d argument, but %d were provided\", fn, len(argv), len(values))\n\t\treturn\n\t}\n\tfor i := range argv {\n\t\targv[i] = reflect.ValueOf(values[i])\n\t}\n\tresult := v.Call(argv)\n\tif len(result) != 1 {\n\t\terr = fmt.Errorf(\"templ-storybook: function %s must return a templ.Component\", name)\n\t\treturn\n\t}\n\toutput, ok := result[0].Interface().(templ.Component)\n\tif !ok {\n\t\terr = fmt.Errorf(\"templ-storybook: result of function %s is not a templ.Component\", name)\n\t\treturn\n\t}\n\treturn output, nil\n}\n\nfunc NewConf(title string, args ...Arg) *Conf {\n\tc := &Conf{\n\t\tTitle: title,\n\t\tParameters: StoryParameters{\n\t\t\tServer: map[string]any{\n\t\t\t\t\"id\": title,\n\t\t\t},\n\t\t},\n\t\tArgs:     NewSortedMap(),\n\t\tArgTypes: NewSortedMap(),\n\t\tStories:  []Story{},\n\t}\n\tfor _, arg := range args {\n\t\tc.Args.Add(arg.Name, arg.Value)\n\t\tc.ArgTypes.Add(arg.Name, map[string]any{\n\t\t\t\"control\": arg.Control,\n\t\t})\n\t}\n\tc.AddStory(\"Default\")\n\treturn c\n}\n\nfunc (c *Conf) AddStory(name string, args ...Arg) {\n\tm := NewSortedMap()\n\tfor _, arg := range args {\n\t\tm.Add(arg.Name, arg.Value)\n\t}\n\tc.Stories = append(c.Stories, Story{\n\t\tName: name,\n\t\tArgs: m,\n\t})\n}\n\n// Controls for the configuration.\n// See https://storybook.js.org/docs/react/essentials/controls\ntype Arg struct {\n\tName    string\n\tValue   any\n\tControl any\n\tGet     func(q url.Values) any\n}\n\nfunc ObjectArg(name string, value any, valuePtr any) Arg {\n\treturn Arg{\n\t\tName:    name,\n\t\tValue:   value,\n\t\tControl: \"object\",\n\t\tGet: func(q url.Values) any {\n\t\t\terr := json.Unmarshal([]byte(q.Get(name)), valuePtr)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn reflect.Indirect(reflect.ValueOf(valuePtr)).Interface()\n\t\t},\n\t}\n}\n\nfunc TextArg(name, value string) Arg {\n\treturn Arg{\n\t\tName:    name,\n\t\tValue:   value,\n\t\tControl: \"text\",\n\t\tGet: func(q url.Values) any {\n\t\t\treturn q.Get(name)\n\t\t},\n\t}\n}\n\nfunc BooleanArg(name string, value bool) Arg {\n\treturn Arg{\n\t\tName:    name,\n\t\tValue:   value,\n\t\tControl: \"boolean\",\n\t\tGet: func(q url.Values) any {\n\t\t\treturn q.Get(name) == \"true\"\n\t\t},\n\t}\n}\n\ntype IntArgConf struct{ Min, Max, Step *int }\n\nfunc IntArg(name string, value int, conf IntArgConf) Arg {\n\tcontrol := map[string]any{\n\t\t\"type\": \"number\",\n\t}\n\tif conf.Min != nil {\n\t\tcontrol[\"min\"] = conf.Min\n\t}\n\tif conf.Max != nil {\n\t\tcontrol[\"max\"] = conf.Max\n\t}\n\tif conf.Step != nil {\n\t\tcontrol[\"step\"] = conf.Step\n\t}\n\targ := Arg{\n\t\tName:    name,\n\t\tValue:   value,\n\t\tControl: control,\n\t\tGet: func(q url.Values) any {\n\t\t\ti64, err := strconv.ParseInt(q.Get(name), 10, 64)\n\t\t\tif err != nil || i64 < math.MinInt || i64 > math.MaxInt {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\treturn int(i64)\n\t\t},\n\t}\n\treturn arg\n}\n\nfunc FloatArg(name string, value float64, min, max, step float64) Arg {\n\treturn Arg{\n\t\tName:  name,\n\t\tValue: value,\n\t\tControl: map[string]any{\n\t\t\t\"type\": \"number\",\n\t\t\t\"min\":  min,\n\t\t\t\"max\":  max,\n\t\t\t\"step\": step,\n\t\t},\n\t\tGet: func(q url.Values) any {\n\t\t\ti, _ := strconv.ParseFloat(q.Get(name), 64)\n\t\t\treturn i\n\t\t},\n\t}\n}\n\ntype Conf struct {\n\tTitle      string          `json:\"title\"`\n\tParameters StoryParameters `json:\"parameters\"`\n\tArgs       *SortedMap      `json:\"args\"`\n\tArgTypes   *SortedMap      `json:\"argTypes\"`\n\tStories    []Story         `json:\"stories\"`\n}\n\ntype StoryParameters struct {\n\tServer map[string]any `json:\"server\"`\n}\n\nfunc NewSortedMap() *SortedMap {\n\treturn &SortedMap{\n\t\tm:        new(sync.Mutex),\n\t\tinternal: map[string]any{},\n\t\tkeys:     []string{},\n\t}\n}\n\ntype SortedMap struct {\n\tm        *sync.Mutex\n\tinternal map[string]any\n\tkeys     []string\n}\n\nfunc (sm *SortedMap) Add(key string, value any) {\n\tsm.m.Lock()\n\tdefer sm.m.Unlock()\n\tsm.keys = append(sm.keys, key)\n\tsm.internal[key] = value\n}\n\nfunc (sm *SortedMap) MarshalJSON() (output []byte, err error) {\n\tsm.m.Lock()\n\tdefer sm.m.Unlock()\n\tb := new(bytes.Buffer)\n\tb.WriteRune('{')\n\tenc := json.NewEncoder(b)\n\tfor i, k := range sm.keys {\n\t\terr = enc.Encode(k)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\t_, err = b.WriteRune(':')\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\terr = enc.Encode(sm.internal[k])\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif i < len(sm.keys)-1 {\n\t\t\t_, err = b.WriteRune(',')\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\tb.WriteRune('}')\n\treturn b.Bytes(), nil\n}\n\ntype Story struct {\n\tName string     `json:\"name\"`\n\tArgs *SortedMap `json:\"args\"`\n}\n"
  },
  {
    "path": "turbo/stream.go",
    "content": "package turbo\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/a-h/templ\"\n)\n\n// Append adds an append action to the output stream.\nfunc Append(w http.ResponseWriter, target string, template templ.Component) error {\n\treturn AppendWithContext(context.Background(), w, target, template)\n}\n\n// AppendWithContext adds an append action to the output stream.\nfunc AppendWithContext(ctx context.Context, w http.ResponseWriter, target string, template templ.Component) error {\n\tw.Header().Set(\"Content-Type\", \"text/vnd.turbo-stream.html\")\n\treturn actionTemplate(\"append\", target).Render(templ.WithChildren(ctx, template), w)\n}\n\n// Prepend adds a prepend action to the output stream.\nfunc Prepend(w http.ResponseWriter, target string, template templ.Component) error {\n\treturn PrependWithContext(context.Background(), w, target, template)\n}\n\n// PrependWithContext adds a prepend action to the output stream.\nfunc PrependWithContext(ctx context.Context, w http.ResponseWriter, target string, template templ.Component) error {\n\tw.Header().Set(\"Content-Type\", \"text/vnd.turbo-stream.html\")\n\treturn actionTemplate(\"prepend\", target).Render(templ.WithChildren(ctx, template), w)\n}\n\n// Replace adds a replace action to the output stream.\nfunc Replace(w http.ResponseWriter, target string, template templ.Component) error {\n\treturn ReplaceWithContext(context.Background(), w, target, template)\n}\n\n// ReplaceWithContext adds a replace action to the output stream.\nfunc ReplaceWithContext(ctx context.Context, w http.ResponseWriter, target string, template templ.Component) error {\n\tw.Header().Set(\"Content-Type\", \"text/vnd.turbo-stream.html\")\n\treturn actionTemplate(\"replace\", target).Render(templ.WithChildren(ctx, template), w)\n}\n\n// Update adds an update action to the output stream.\nfunc Update(w http.ResponseWriter, target string, template templ.Component) error {\n\treturn UpdateWithContext(context.Background(), w, target, template)\n}\n\n// UpdateWithContext adds an update action to the output stream.\nfunc UpdateWithContext(ctx context.Context, w http.ResponseWriter, target string, template templ.Component) error {\n\tw.Header().Set(\"Content-Type\", \"text/vnd.turbo-stream.html\")\n\treturn actionTemplate(\"update\", target).Render(templ.WithChildren(ctx, template), w)\n}\n\n// Remove adds a remove action to the output stream.\nfunc Remove(w http.ResponseWriter, target string) error {\n\treturn RemoveWithContext(context.Background(), w, target)\n}\n\n// RemoveWithContext adds a remove action to the output stream.\nfunc RemoveWithContext(ctx context.Context, w http.ResponseWriter, target string) error {\n\tw.Header().Set(\"Content-Type\", \"text/vnd.turbo-stream.html\")\n\treturn removeTemplate(\"remove\", target).Render(ctx, w)\n}\n\n// IsTurboRequest returns true if the incoming request is able to receive a Turbo stream.\n// This is determined by checking the request header for \"text/vnd.turbo-stream.html\"\nfunc IsTurboRequest(r *http.Request) bool {\n\treturn strings.Contains(r.Header.Get(\"accept\"), \"text/vnd.turbo-stream.html\")\n}\n"
  },
  {
    "path": "turbo/stream.templ",
    "content": "package turbo\n\ntempl actionTemplate(action string, target string) {\n\t<turbo-stream action={ action } target={ target }>\n\t\t<template>\n\t\t\t{ children... }\n\t\t</template>\n\t</turbo-stream>\n}\n\ntempl removeTemplate(action string, target string) {\n\t<turbo-stream action={ action } target={ target }></turbo-stream>\n}\n"
  },
  {
    "path": "turbo/stream_templ.go",
    "content": "// Code generated by templ - DO NOT EDIT.\n\npackage turbo\n\n//lint:file-ignore SA4006 This context is only used if a nested component is present.\n\nimport \"github.com/a-h/templ\"\nimport templruntime \"github.com/a-h/templ/runtime\"\n\nfunc actionTemplate(action string, target string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var1 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var1 == nil {\n\t\t\ttempl_7745c5c3_Var1 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, \"<turbo-stream action=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var2 string\n\t\ttempl_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(action)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `turbo/stream.templ`, Line: 4, Col: 30}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, \"\\\" target=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var3 string\n\t\ttempl_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(target)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `turbo/stream.templ`, Line: 4, Col: 48}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, \"\\\"><template>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, \"</template></turbo-stream>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc removeTemplate(action string, target string) templ.Component {\n\treturn templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {\n\t\ttempl_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context\n\t\tif templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {\n\t\t\treturn templ_7745c5c3_CtxErr\n\t\t}\n\t\ttempl_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)\n\t\tif !templ_7745c5c3_IsBuffer {\n\t\t\tdefer func() {\n\t\t\t\ttempl_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)\n\t\t\t\tif templ_7745c5c3_Err == nil {\n\t\t\t\t\ttempl_7745c5c3_Err = templ_7745c5c3_BufErr\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\tctx = templ.InitializeContext(ctx)\n\t\ttempl_7745c5c3_Var4 := templ.GetChildren(ctx)\n\t\tif templ_7745c5c3_Var4 == nil {\n\t\t\ttempl_7745c5c3_Var4 = templ.NopComponent\n\t\t}\n\t\tctx = templ.ClearChildren(ctx)\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, \"<turbo-stream action=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var5 string\n\t\ttempl_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(action)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `turbo/stream.templ`, Line: 12, Col: 30}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, \"\\\" target=\\\"\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\tvar templ_7745c5c3_Var6 string\n\t\ttempl_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(target)\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ.Error{Err: templ_7745c5c3_Err, FileName: `turbo/stream.templ`, Line: 12, Col: 48}\n\t\t}\n\t\t_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\ttempl_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, \"\\\"></turbo-stream>\")\n\t\tif templ_7745c5c3_Err != nil {\n\t\t\treturn templ_7745c5c3_Err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar _ = templruntime.GeneratedTemplate\n"
  },
  {
    "path": "turbo/stream_test.go",
    "content": "package turbo\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/a-h/templ/internal/htmlfind\"\n\t\"golang.org/x/net/html\"\n)\n\nvar contentTemplate = templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {\n\t_, err := io.WriteString(w, \"content\")\n\treturn err\n})\n\nfunc TestStreamReplace(t *testing.T) {\n\t// Arrange.\n\tw := httptest.NewRecorder()\n\n\tif err := Replace(w, \"replaceTarget\", contentTemplate); err != nil {\n\t\tt.Fatalf(\"replace failed: %v\", err)\n\t}\n\n\t// Act.\n\tbdy := w.Body.Bytes()\n\tdoc, err := html.Parse(bytes.NewReader(bdy))\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read response: %v\", err)\n\t}\n\n\t// Assert.\n\tmatch := htmlfind.Element(\"turbo-stream\", htmlfind.Attr(\"action\", \"replace\"), htmlfind.Attr(\"target\", \"replaceTarget\"))\n\tvar count int\n\tfor _, node := range htmlfind.All(doc, match) {\n\t\tcount++\n\t\tif strings.TrimSpace(node.FirstChild.FirstChild.Data) != \"content\" {\n\t\t\tt.Errorf(\"expected 'content' to be the text, but got %q\\n%s\", node.FirstChild.Data, bdy)\n\t\t}\n\t}\n\tif count != 1 {\n\t\tt.Errorf(\"expected to find a single replace action, but found %d\", count)\n\t}\n}\n\nfunc TestStream(t *testing.T) {\n\tw := httptest.NewRecorder()\n\n\t// Append.\n\texpectedAppends := 2\n\tfor range expectedAppends {\n\t\tif err := Append(w, \"appendTarget\", contentTemplate); err != nil {\n\t\t\tt.Fatalf(\"append failed: %v\", err)\n\t\t}\n\t}\n\t// Prepend.\n\texpectedPrepends := 3\n\tfor range expectedPrepends {\n\t\tif err := Prepend(w, \"prependTarget\", contentTemplate); err != nil {\n\t\t\tt.Fatalf(\"prepend failed: %v\", err)\n\t\t}\n\t}\n\t// Replace.\n\texpectedReplaces := 4\n\tfor range expectedReplaces {\n\t\tif err := Replace(w, \"replaceTarget\", contentTemplate); err != nil {\n\t\t\tt.Fatalf(\"replace failed: %v\", err)\n\t\t}\n\t}\n\t// Update.\n\texpectedUpdates := 5\n\tfor range expectedUpdates {\n\t\tif err := Update(w, \"updateTarget\", contentTemplate); err != nil {\n\t\t\tt.Fatalf(\"update failed: %v\", err)\n\t\t}\n\t}\n\t// Remove.\n\texpectedRemoves := 6\n\tfor range expectedRemoves {\n\t\tif err := Remove(w, \"removeTarget\"); err != nil {\n\t\t\tt.Fatalf(\"remove failed: %v\", err)\n\t\t}\n\t}\n\n\tdoc, err := html.Parse(w.Body)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read response: %v\", err)\n\t}\n\n\tappends := htmlfind.All(doc, htmlfind.Element(\"turbo-stream\", htmlfind.Attr(\"action\", \"append\"), htmlfind.Attr(\"target\", \"appendTarget\")))\n\tif len(appends) != expectedAppends {\n\t\tt.Errorf(\"expected %d append actions, but got %d\", expectedAppends, len(appends))\n\t}\n\tprepends := htmlfind.All(doc, htmlfind.Element(\"turbo-stream\", htmlfind.Attr(\"action\", \"prepend\"), htmlfind.Attr(\"target\", \"prependTarget\")))\n\tif len(prepends) != expectedPrepends {\n\t\tt.Errorf(\"expected %d prepend actions, but got %d\", expectedPrepends, len(prepends))\n\t}\n\treplaces := htmlfind.All(doc, htmlfind.Element(\"turbo-stream\", htmlfind.Attr(\"action\", \"replace\"), htmlfind.Attr(\"target\", \"replaceTarget\")))\n\tif len(replaces) != expectedReplaces {\n\t\tt.Errorf(\"expected %d replace actions, but got %d\", expectedReplaces, len(replaces))\n\t}\n\tupdates := htmlfind.All(doc, htmlfind.Element(\"turbo-stream\", htmlfind.Attr(\"action\", \"update\"), htmlfind.Attr(\"target\", \"updateTarget\")))\n\tif len(updates) != expectedUpdates {\n\t\tt.Errorf(\"expected %d update actions, but got %d\", expectedUpdates, len(updates))\n\t}\n\tremoves := htmlfind.All(doc, htmlfind.Element(\"turbo-stream\", htmlfind.Attr(\"action\", \"remove\"), htmlfind.Attr(\"target\", \"removeTarget\")))\n\tif len(removes) != expectedRemoves {\n\t\tt.Errorf(\"expected %d remove actions, but got %d\", expectedRemoves, len(removes))\n\t}\n\tif w.Result().Header.Get(\"Content-Type\") != \"text/vnd.turbo-stream.html\" {\n\t\tt.Errorf(\"expected Content-Type %q, got %q\", \"text/vnd.turbo-stream.html\", w.Result().Header.Get(\"Content-Type\"))\n\t}\n}\n\nfunc TestIsTurboRequest(t *testing.T) {\n\tturboRequest := httptest.NewRequest(\"GET\", \"/\", nil)\n\tif IsTurboRequest(turboRequest) {\n\t\tt.Error(\"request was incorrectly recognised as a Turbo stream request\")\n\t}\n\tturboRequest.Header.Add(\"accept\", \"text/vnd.turbo-stream.html\")\n\tif !IsTurboRequest(turboRequest) {\n\t\tt.Error(\"request not correctly recognised as a Turbo stream request\")\n\t}\n}\n"
  },
  {
    "path": "url.go",
    "content": "package templ\n\nimport (\n\t\"errors\"\n\t\"strings\"\n)\n\n// FailedSanitizationURL is returned if a URL fails sanitization checks.\nconst FailedSanitizationURL = SafeURL(\"about:invalid#TemplFailedSanitizationURL\")\n\n// URL sanitizes the input string s and returns a SafeURL.\nfunc URL(s string) SafeURL {\n\tif i := strings.IndexRune(s, ':'); i >= 0 && !strings.ContainsRune(s[:i], '/') {\n\t\tprotocol := s[:i]\n\t\tif !strings.EqualFold(protocol, \"http\") && !strings.EqualFold(protocol, \"https\") && !strings.EqualFold(protocol, \"mailto\") && !strings.EqualFold(protocol, \"tel\") && !strings.EqualFold(protocol, \"ftp\") && !strings.EqualFold(protocol, \"ftps\") {\n\t\t\treturn FailedSanitizationURL\n\t\t}\n\t}\n\treturn SafeURL(s)\n}\n\n// SafeURL is a URL that has been sanitized.\ntype SafeURL string\n\n// JoinURLErrs joins an optional list of errors and returns a sanitized SafeURL.\nfunc JoinURLErrs[T ~string](s T, errs ...error) (SafeURL, error) {\n\tif safeURL, ok := any(s).(SafeURL); ok {\n\t\treturn safeURL, errors.Join(errs...)\n\t}\n\treturn URL(string(s)), errors.Join(errs...)\n}\n"
  },
  {
    "path": "url_test.go",
    "content": "package templ\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"testing\"\n)\n\ntype urlTest struct {\n\turl             string\n\texpectSanitized bool\n}\n\nvar urlTests = []urlTest{\n\t{\"//example.com\", false},\n\t{\"/\", false},\n\t{\"/index\", false},\n\t{\"http://example.com\", false},\n\t{\"https://example.com\", false},\n\t{\"mailto:test@example.com\", false},\n\t{\"tel:+1234567890\", false},\n\t{\"ftp://example.com\", false},\n\t{\"ftps://example.com\", false},\n\t{\"irc://example.com\", true},\n\t{\"bitcoin://example.com\", true},\n}\n\nfunc testURL(t *testing.T, url string, expectSanitized bool) {\n\tu := URL(url)\n\twasSanitized := u == FailedSanitizationURL\n\tif expectSanitized != wasSanitized {\n\t\tt.Errorf(\"expected sanitized=%v, got %v\", expectSanitized, wasSanitized)\n\t}\n}\n\nfunc TestURL(t *testing.T) {\n\tfor _, test := range urlTests {\n\t\tt.Run(test.url, func(t *testing.T) {\n\t\t\ttestURL(t, test.url, test.expectSanitized)\n\t\t})\n\t\ttest.url = strings.ToUpper(test.url)\n\t\tt.Run(strings.ToUpper(test.url), func(t *testing.T) {\n\t\t\ttestURL(t, test.url, test.expectSanitized)\n\t\t})\n\t}\n}\n\nfunc BenchmarkURL(b *testing.B) {\n\tfor range b.N {\n\t\tfor _, test := range urlTests {\n\t\t\tu := URL(test.url)\n\t\t\twasSanitized := u == FailedSanitizationURL\n\t\t\tif test.expectSanitized != wasSanitized {\n\t\t\t\tb.Errorf(\"expected sanitized=%v, got %v\", test.expectSanitized, wasSanitized)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestJoinURLErrs(t *testing.T) {\n\terr1 := errors.New(\"error 1\")\n\terr2 := errors.New(\"error 2\")\n\n\ttype CustomString string\n\n\tcheckResult := func(t *testing.T, result SafeURL, err error, expected SafeURL, expectedErrs ...error) {\n\t\tt.Helper()\n\t\tif result != expected {\n\t\t\tt.Errorf(\"expected result %q, got %q\", expected, result)\n\t\t}\n\t\tif len(expectedErrs) == 0 {\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"expected nil error, got %v\", err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif err == nil {\n\t\t\tt.Errorf(\"expected error(s) %v, got nil\", expectedErrs)\n\t\t\treturn\n\t\t}\n\t\tfor _, exp := range expectedErrs {\n\t\t\tif !errors.Is(err, exp) {\n\t\t\t\tt.Errorf(\"expected error to contain %v, but it did not\", exp)\n\t\t\t}\n\t\t}\n\t}\n\tt.Run(\"strings are sanitized\", func(t *testing.T) {\n\t\tresult, err := JoinURLErrs(\"javascript:alert(1)\")\n\t\tcheckResult(t, result, err, FailedSanitizationURL)\n\t})\n\tt.Run(\"custom string types are sanitized\", func(t *testing.T) {\n\t\tresult, err := JoinURLErrs(CustomString(\"javascript:alert(1)\"))\n\t\tcheckResult(t, result, err, FailedSanitizationURL)\n\t})\n\tt.Run(\"SafeURLs bypass sanitization\", func(t *testing.T) {\n\t\tsafeURL := SafeURL(\"javascript:alert(1)\")\n\t\tresult, err := JoinURLErrs(safeURL)\n\t\tcheckResult(t, result, err, safeURL)\n\t})\n\tt.Run(\"safe URL strings are returned unchanged\", func(t *testing.T) {\n\t\tresult, err := JoinURLErrs(\"https://example.com\")\n\t\tcheckResult(t, result, err, SafeURL(\"https://example.com\"))\n\t})\n\tt.Run(\"single errors are joined\", func(t *testing.T) {\n\t\tresult, err := JoinURLErrs(\"https://example.com\", err1)\n\t\tcheckResult(t, result, err, SafeURL(\"https://example.com\"), err1)\n\t})\n\tt.Run(\"multiple errors are joined\", func(t *testing.T) {\n\t\tresult, err := JoinURLErrs(\"https://example.com\", err1, err2)\n\t\tcheckResult(t, result, err, SafeURL(\"https://example.com\"), err1, err2)\n\t})\n\tt.Run(\"nil errors are preserved\", func(t *testing.T) {\n\t\tresult, err := JoinURLErrs(\"https://example.com\", nil)\n\t\tcheckResult(t, result, err, SafeURL(\"https://example.com\"))\n\t})\n}\n"
  },
  {
    "path": "version.go",
    "content": "package templ\n\nimport _ \"embed\"\n\n//go:embed .version\nvar version string\n\nfunc Version() string {\n\treturn \"v\" + version\n}\n"
  },
  {
    "path": "watchmode.go",
    "content": "package templ\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// WriteWatchModeString is used when rendering templates in development mode.\n// the generator would have written non-go code to the _templ.txt file, which\n// is then read by this function and written to the output.\n//\n// Deprecated: since templ v0.3.x generated code uses WriteString.\nfunc WriteWatchModeString(w io.Writer, lineNum int) error {\n\t_, path, _, _ := runtime.Caller(1)\n\tif !strings.HasSuffix(path, \"_templ.go\") {\n\t\treturn errors.New(\"templ: WriteWatchModeString can only be called from _templ.go\")\n\t}\n\ttxtFilePath := strings.Replace(path, \"_templ.go\", \"_templ.txt\", 1)\n\n\tliterals, err := getWatchedStrings(txtFilePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"templ: failed to cache strings: %w\", err)\n\t}\n\n\tif lineNum > len(literals) {\n\t\treturn fmt.Errorf(\"templ: failed to find line %d in %s\", lineNum, txtFilePath)\n\t}\n\n\ts, err := strconv.Unquote(`\"` + literals[lineNum-1] + `\"`)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = io.WriteString(w, s)\n\treturn err\n}\n\nvar (\n\twatchModeCache  = map[string]watchState{}\n\twatchStateMutex sync.Mutex\n)\n\ntype watchState struct {\n\tmodTime time.Time\n\tstrings []string\n}\n\nfunc getWatchedStrings(txtFilePath string) ([]string, error) {\n\twatchStateMutex.Lock()\n\tdefer watchStateMutex.Unlock()\n\n\tstate, cached := watchModeCache[txtFilePath]\n\tif !cached {\n\t\treturn cacheStrings(txtFilePath)\n\t}\n\n\tif time.Since(state.modTime) < time.Millisecond*100 {\n\t\treturn state.strings, nil\n\t}\n\n\tinfo, err := os.Stat(txtFilePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to stat %s: %w\", txtFilePath, err)\n\t}\n\n\tif !info.ModTime().After(state.modTime) {\n\t\treturn state.strings, nil\n\t}\n\n\treturn cacheStrings(txtFilePath)\n}\n\nfunc cacheStrings(txtFilePath string) ([]string, error) {\n\ttxtFile, err := os.Open(txtFilePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to open %s: %w\", txtFilePath, err)\n\t}\n\tdefer func() {\n\t\t_ = txtFile.Close()\n\t}()\n\n\tinfo, err := txtFile.Stat()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to stat %s: %w\", txtFilePath, err)\n\t}\n\n\tall, err := io.ReadAll(txtFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"templ: failed to read %s: %w\", txtFilePath, err)\n\t}\n\n\tliterals := strings.Split(string(all), \"\\n\")\n\twatchModeCache[txtFilePath] = watchState{\n\t\tmodTime: info.ModTime(),\n\t\tstrings: literals,\n\t}\n\n\treturn literals, nil\n}\n"
  }
]